awk가 여러 파일을 처리하는 데 문제가 있습니다.

awk가 여러 파일을 처리하는 데 문제가 있습니다.

내 입력 파일에는 콜론으로 구분된 필드가 있습니다.

기본:

one:111:222:333
fiv:333:222:333
two:123:234:500

파일 1:

one:111:222:333
two:123:234:501

파일 2:

one:111:222:333
thr:-:234:232
fiv:999:500:232

팁 고마워협회awk 코드를 일부 수정했습니다.

$ awk -F':' -vf=main 'FILENAME==f{m=$0};FILENAME!=f&&$2~/[0-9]+/{if ($2~/[0-9]+/&&(!($1 in a) || $3 > a[$1])) { a[$1] = $3; b[$1] = $0 } next;}{if (($1 in a) && (a[$1] > $3)){ print b[$1]":updated:"m; delete b[$1] } else print; }' file* main
thr:-:234:232
one:111:222:333
fiv:999:500:232:updated:fiv:333:222:333
two:123:234:500

왜 줄도 인쇄합니까 thr:-:234:232? thr기본 파일에서는 아무 일도 발생하지 않으므로 해당 파일의 모든 업데이트는 무시되어야 합니다 . 업데이트는 기본 파일에 있는 첫 번째 열의 행과 file1 또는 file2에 존재하고 세 번째 열에 더 큰 값을 갖는 첫 번째 열에 해당하는 행만을 기반으로 해야 합니다.

여기서는 왜 $2~/[0-9]+/작동하지 않나요?

업데이트: 아직 확실하지 않습니다. 다음을 살펴보세요.

테스트 메인 파일을 다음과 같이 수정하면:

one:111:222:333 fiv:333:222:333 two:123:234:500 ten.233:422:452

그리고 다음 awk 명령을 실행하세요:

$ awk -F':' -vf=main 'FILENAME==f{m=$0};FILENAME!=f&&$2~/[0-9]+/{if ($2~/[0-9]+/&&(!($1 in a) || $3 > a[$1])) { a[$1] = $3; b[$1] = $0 } next;}{if (($1 in a) && (a[$1] > $3)){ print b[$1]":updated:"m; delete b[$1] } else print; }' file* main
thr:-:234:232
one:111:222:333
fiv:999:500:232:updated:fiv:333:222:333
two:123:234:500
ten.233:422:452

따라서 thr 라인은 파일에 thr없기 때문에 출력에 있어서는 안 되기 때문에 출력이 잘못되었습니다.main

추가 조건을 추가하여 명령을 수정했지만 else if($1 in a) {print}; 기본 파일에 "ten"으로 시작하는 줄이 인쇄되지 않습니다.

$ awk -F':' -vf=main 'FILENAME==f{m=$0};FILENAME!=f&&$2~/[0-9]+/{if ($2~/[0-9]+/&&(!($1 in a) || $3 > a[$1])) { a[$1] = $3; b[$1] = $0 } next;}{if (($1 in a) && (a[$1] > $3)){ print b[$1]":updated:"m; delete b[$1] } else if($1 in a) {print}; }' file* main
one:111:222:333
fiv:999:500:232:updated:fiv:333:222:333
two:123:234:500

어떤 도움이라도 정말 감사하겠습니다.

awk는 정말 훌륭합니다. 불행히도 저는 프로그래머가 아니기 때문에 아직 스스로 알아낼 수 없습니다.

답변1

next블록에 조건이 있기 때문입니다 FILENAME != f && $2 ~ /[0-9]+/. 행 이 thr해당 조건을 충족하지 않으므로 "모든 행" 블록에 속합니다. 거기에는 $1이 존재하지 않으므로 a블록 else이 입력되고 해당 행이 인쇄됩니다.

나는 당신이 프로그램을 실제로 볼 수 있도록 합리적인 들여쓰기를 사용한다면 이것을 스스로 알아낼 수 있다고 믿습니다.

awk -F':' -vf=main '
    FILENAME == f {m = $0}
    FILENAME != f && $2 ~ /[0-9]+/ {
        if ($2 ~ /[0-9]+/ && (!($1 in a) || $3 > a[$1])) { 
            a[$1] = $3
            b[$1] = $0 
        } 
        next
    }
    {
        if (($1 in a) && (a[$1] > $3)) { 
            print b[$1]":updated:"m
            delete b[$1] 
        } else 
            print
    }
' file* main

관련 정보