특정 필드별로 비교해야 하는 두 개의 파일이 있습니다.
참조 문서:
42:B:0
43:A:1
44:A:1
45:A:1
대상 파일:
42:!:1
43:B:0
44:A:1
45:B:2
내가 필요한 것은 "while" 루프 + awk를 결합하여 이미 달성할 수 있습니다.
$ cat reference|while IFS=: read a b c;do awk -F: -va=$a -vb=$b -vc=$c '$1==a{if($2!=b){if($3>c)if($2!="!"){ print a":target has bigger $3("$3">"c") and $2 different ("$2")" } else { print a":target has bigger $3("$3">"c") but $2 disabled ("$2")" }}}' target;done
42:target has bigger $3(1>0) but $2 disabled (!)
45:target has bigger $3(2>1) and $2 different (B)
어떻게 "while" 루프에서 벗어나 이 두 파일을 awk에서 직접 처리할 수 있나요?
답변1
awk -F: '
FNR == NR { c2[$1] = $2; c3[$1] = $3; next }
!($1 in c2) {
printf("%d: $1 not found in reference\n", $1)
next
}
$3 > c3[$1] && $2 == "!" {
printf("%d: target has bigger $3 (%d>%d) but disabled $2 (%s)\n", $1,$3,c3[$1],$2)
next
}
$3 > c3[$1] && $2 != c2[$1] {
printf("%d: target has bigger $3 (%d>%d) but different $2 (%s)\n", $1,$3,c3[$1],$2)
}' reference target
그러면 참조 파일을 읽은 다음 대상 파일을 읽습니다.
참조 파일을 읽으면( ) FNR == NR
배열과 . 사용되는 인덱스는 첫 번째 열의 값입니다.c2
c3
대상 파일( FNR != NR
)을 읽으면 세 번째 열의 값을 배열에 있는 값과 비교합니다 c3
. 그런 다음 !
두 번째 열을 의 참조 파일에 저장된 두 번째 열과 비교합니다 c2
.
또한 코드는 대상 파일의 첫 번째 열이 참조 파일에서 발견되지 않으면 추가 메시지를 내보냅니다.
질문의 데이터가 주어지고 56:C:9
대상 행의 출력( )을 추가하면 다음과 같습니다.
42: target has bigger $3 (1>0) but disabled $2 (!)
45: target has bigger $3 (2>1) but different $2 (B)
56: $1 not found in reference
답변2
paste
+awk
마법:
paste -d':' reference target | awk -F':' \
'$1 == $4 && $2 != $5 && $6 > $3{
if ($5 == "!"){ p = "but"; state = "disabled" }
else { p = "and"; state = "different" }
printf "%s:target has bigger $3(%d > %d) %s $2 %s (%s)\n", $1, $6, $3, p, state, $5
}'
산출:
42:target has bigger $3(1 > 0) but $2 disabled (!)
45:target has bigger $3(2 > 1) and $2 different (B)
보너스gawk
해결 방법(첫 번째 필드 값이 순서가 있고 고유하다는 점을 고려):
awk -F':' \
'NR == FNR{
a[NR][1] = $1; a[NR][2] = $2; a[NR][3] = $3; next
}
$1 == a[FNR][1] && $2 != a[FNR][2] && $3 > a[FNR][3]{
if ($2 == "!"){ p = "but"; state = "disabled" }
else { p = "and"; state = "different" }
printf "%s:target has bigger $3(%d > %d) %s $2 %s (%s)\n", $1, $3, a[FNR][3], p, state, $2
}' reference target