AWK에서 고유 배열 인쇄

AWK에서 고유 배열 인쇄

두 파일을 비교하여 ID 번호가 일치하는 레코드만 인쇄하고 중복 레코드는 인쇄하지 않으려고 합니다.

두 개의 파일이 있습니다.

file1.txt포함하다:

Simons 0987768798980
West 09809867678
Vickers 768774564650
Simons 76867790987
Peterson 24346576865
Simons 76867790987
Holister 87879655456
Peterson 87686765766

그리고 다음 file2.txt을 포함합니다:

768774564650 Harry
76867790987 Steve
0987768798980 Mary
0987768798980 Mary
76856009097 Ali
87879655456 Rick
87686765766 Martin

원하는 결과는 다음과 같습니다.

Harry Vickers 768774564650
Steve Simons 76867790987
Mary Simons 0987768798980   
Rick Holister 87879655456
Martin Peterson 87686765766

내가 시도한 것은 다음과 같습니다.

ARGV[1]==FILENAME{id2lastname[$2]=$1;id2id[$2]=$2}
ARGV[2]==FILENAME{id2firstname[$1]=$2}

$1 in id2id{print id2firstname[$1],id2lastname[$1],id2id[$1],id2firstname[$1]="",id2id[$1]="",id2lastname[$1]=""}

다음과 같은 출력이 생성됩니다.

Harry Vickers 768774564650   
Steve Simons 76867790987   
Mary Simons 0987768798980   
Mary     
Rick Holister 87879655456   
Martin Peterson 87686765766 

중복 기록의 성, 주민등록번호는 삭제됐는데 이름은 그대로 유지된 이유를 알고 싶습니다.

이 기술이 이상하거나 틀에 얽매이지 않았다면 죄송합니다. 나는 오랫동안 공부하지 않았습니다.

내 시도로 문제가 해결되지 않거나 더 나은 방법이 있다고 생각되면 다른 방식으로 원하는 결과를 얻을 수 있어서 기쁘지만 다음과 같이 하십시오.

  • GAWK를 사용하면서 (계속 사용하고 싶기 때문에)
  • 간단하게 유지하려고 노력하세요.
  • 그리고 그것이 어떻게 작동하는지 설명하면 뭔가를 배울 수 있습니다.

답변1

부분 줄이 인쇄되는 이유는 코드에서 배열에서 제거하려는 값을 삭제하는 대신 해당 값을 빈 문자열로 바꾸기 때문입니다.

이로 인해 검사가 빈 문자열 값 $1 in id2id{ ... }으로 평가됩니다 .true

해결책은 코드를 다음으로 바꾸는 것입니다 . id2id[$1]=""그러면 delete id2id[$1]예상대로 작동합니다.

다음은 약간 단순화된 코드 버전입니다.

awk 'NR == FNR { a[$2] = $1; next }
     $1 in a { print a[$1], $2, $1; delete a[$1] }' file1.txt file2.txt

한 줄에:

awk 'NR==FNR{a[$2]=$1;next} $1 in a{print a[$1],$2,$1; delete a[$1]}' file1.txt file2.txt

Join 대신 awk를 사용하면 단순성과 사용자 정의가 쉽다는 장점이 있습니다.

단점은 병합 전 첫 번째 파일이 RAM에 저장되므로 대용량 파일을 효율적으로 처리할 수 없다는 점입니다.

답변2

필요에 따라 사용 join하고 가능한 한 간단하게 만드십시오.

join -1 2 -2 1 -o 2.2 1.1 2.1 <(sort -unk2,2 file1) <(sort -unk1,1 file2) 2>/dev/null

join첫 번째 파일의 두 번째 필드에서 -1 2두 번째 파일의 첫 번째 필드를 -2 1키로 사용합니다.

-o다음 필드를 출력합니다. 두
번째 파일의 두 번째 필드 2.2
첫 번째 파일의 첫 번째 필드 1.1
및 두 번째 파일의 첫 번째 필드2.1

이렇게 하면 두 번째 필드의 첫 번째 파일이 숫자 키로 정렬되고 sort -unk2,2 file1
첫 번째 필드의 두 번째 파일이 숫자 키로 정렬되어 sort -unk1,1 file2 두 파일에서 중복 항목이 제거됩니다.-u


해결책:

awk '!second_file{ Ids[$2]=$1; next }
     ($1 in Ids) { print $2, Ids[$1], $1 }' file1 second_file=1 <(sort -u file2)

관련 정보