
파일이 있어요
XYZ 123 S S R O O S F
PQR 456 F S S R O F F
ABC 789 F S R S S F S
이제 전체 행에서 "R" &&를 찾은 다음 "O" 또는 "S"를 찾으면 열 번호를 가져오고 열 번호를 기반으로 명령을 수행해야 하며 이것이 사실이면 R 및 O 대신 L을 표시합니다. 또는 S가 거짓인 경우 R 대신 F를 사용하고 O(모든 연속 O에 대해) 대신 F를 사용하거나 S를 사용합니다.
이제 아니요 열에서 날짜를 결정하겠습니다.
첫 번째 행 R이 5에 있다고 가정하면 날짜는 열 번호 - 3, 즉 두 번째가 됩니다.
두 번째 행 날짜의 경우 6-3, 즉 세 번째, 세 번째 행이 다시 5-3, 즉 두 번째,
그래서 나는 변수 date=%m/d(3번 열에서)/%Y를 사용할 것입니다.
이제 명령은 입니다 ./bpimagelist -client <column 1> -policy <column 2> -hoursago 100000 -U | awk -v date="$date" '$1 == date' | wc -l
. 이제 값이 0이면 false이고 gt 0이면 true입니다.
XYZ is false
PQR is true
ABC is true
그러면 출력은 다음과 같아야합니다
XYZ 123 S S F F F S F
PQR 456 F S S L O F F
ABC 789 F S L S S F S
Valentin에 따르면 몇 가지 변경을 한 후에는 정상적으로 작동하는 것으로 보이는 코드입니다.
while read line;
do
day="$(echo $line | awk '{for (i=1; i<=NF; i++) { if($i == "R") { print i - 2; exit} } }')"
if [[ ${#day} -lt 2 ]]; then day="0${day}"; fi
month=`date '+%m'`
year=`date '+%Y'`
date=`echo $month/$day/$year`
result=$(sudo /usr/openv/netbackup/bin/admincmd/bpimagelist -client "$(echo $line | awk '{print $1}')" -policy "$(echo $line | awk '{print $2}')" -hoursago 100000 -U | awk -v date="$date" '$1 == date' | wc -l)
if [[ $result -ne 0 ]];
then
echo $line | sed 's/ R / L /'
else
echo $line | awk '{
afterR=0;
for (i=1; i<=NF; i++){
if ($i == "R") {
$i = "F";
afterR=1;
}
if (afterR == 1 && $i == "O") {
$i = "F"
}
}
print $0
}'
fi
done < temp
그러나 한 가지 작은 쿼리는 R 뒤에 O가 올 때만 O 이외의 항목을 찾을 때까지 이러한 변경을 수행해야 한다는 것입니다.
입력 파일이 다음과 같으면 어떤 변경도 수행해서는 안 된다는 의미입니다.
XYZ 123 S S R O O O O
이는 R이 O로만 계속됨을 의미하므로 변경을 수행할 필요가 없습니다. 그렇지 않으면 O 이외의 다른 항목이 발견되어 변경을 수행합니다.
답변1
귀하의 요청에 단계별로 답변해 드리겠습니다. 여기서는 input
입력 파일의 한 줄 이라고 가정해 보세요 .
첫 번째 "R" 문자의 열 번호 추출
이는 다음과 같은 경우 매우 간단한 작업입니다 awk
.
awk '{for (i=1; i<=NF; i++) { if($i == "R") { print i - 3; exit} } }' < input
날짜를 계산하는 방법을 고려할 때 'R'이 첫 번째 행에 있을 수 없다고 가정합니다(그렇지 않으면 날짜 숫자가 0이 될 수 있음).
첫 번째 및 두 번째 열의 값 추출
이것은 훨씬 더 간단합니다:
awk '{print $1}' < input # for first column
awk '{print $2}' < input # for second column
출력 구성
명령이 반환되는 경우 True
:
sed 's/ R / L /' < input
명령이 반환되는 경우 False
:
awk '{
afterR=0;
for (i=1; i<=NF; i++){
if ($i == "R") {
$i = "F";
afterR=1;
}
if (afterR == 1 && $i == "O") {
$i = "F"
}
}
print $0
}' < input
함께 모아서
이것이 눈살을 찌푸리게 하지만 각 줄에 대해 매우 구체적인 명령을 실행해야 하기 때문에 입력 줄에 대한 루프를 피할 수 있는 방법이 없습니다. 대용량 파일의 경우 속도가 매우 느려질 수 있습니다. 이러한 모든 요소를 포함하는 스크립트의 모양은 다음과 같습니다.
while read line;
do
date="%m/d$(echo $line | awk '{for (i=1; i<=NF; i++) { if($i == "R") { print i - 3; exit} } }')/%Y"
result=$(./bpimagelist -client "$(echo $line | awk '{print $1}')" -policy "$(echo $line | awk '{print $2}')" -hoursago 100000 -U | awk -v date="$date" '$1 == date' | wc -l)
if [[ $result -ne 0 ]];
then
echo $line | sed 's/ R / L /'
else
echo $line | awk '{
afterR=0;
for (i=1; i<=NF; i++){
if ($i == "R") {
$i = "F";
afterR=1;
}
if (afterR == 1 && $i == "O") {
$i = "F"
}
}
print $0
}'
fi
done < myinputfile.txt