명령줄 및 스크립트에서 awk를 사용한 중복 제거

명령줄 및 스크립트에서 awk를 사용한 중복 제거

다음 형식의 파일이 있습니다.

487422,Potenza
487386,Forlì-Cesena
487399,Grosseto
487425,Catanzaro
487409,Napoli
487446,Prato
495498,Fermo
487425,Catanzaro
487389,Macerata
487442,Biella
487351,Asti
487424,Cosenza
487404,Roma
487359,Como
487404,Roma
487401,Terni
487420,Brindisi
487397,Arezzo
487348,Vercelli
487382,Modena
487356,Genova
487365,Cremona
487369,Verona
487386,Forlì-Cesena

보시다시피 중복된 내용이 포함된 쉼표로 구분된 텍스트입니다. 을 사용하여 열 1과 관련된 텍스트의 중복을 제거하고 싶습니다 awk.

명령줄

쉘 인터페이스를 사용하면 다음과 같은 결과가 나타납니다.

487422,Potenza
487386,Forlì-Cesena
487399,Grosseto
487425,Catanzaro
487409,Napoli
487446,Prato
495498,Fermo
487389,Macerata
487442,Biella
487351,Asti
487424,Cosenza
487404,Roma
487359,Como
487401,Terni
487420,Brindisi
487397,Arezzo
487348,Vercelli
487382,Modena
487356,Genova
487365,Cremona
487369,Verona

이것이 내가 다음 명령에서 기대하는 것입니다

awk -F"," '!a[$1]++' filename.csv

Awk 스크립트

다음과 같이 작성된 awk 스크립트를 사용하면

#!/bin/awk -f

BEGIN {
    FS=","
}
{
    {!a[$1]++}
}

나는 어떤 결과도 얻지 못한다. 스크립트에 문제가 있나요? 스크립트와 명령줄의 동작이 다른 이유는 무엇입니까?

답변1

중괄호 외부 !a[$1]++에는상태{print}, true(0이 아님)로 평가되면 기본 작업을 트리거합니다 .

중괄호 {{!a[$1]++}}안에는행동부작용 없이 무조건 평가되는 것입니다. 버팀대를 제거하십시오:

#!/bin/awk -f

BEGIN {
    FS=","
}

!a[$1]++

답변2

@steeldriver의 이상한 답변정확하고 아마도 필요한 전부일 것입니다. 그러나 입력이 방대해지면 메모리가 부족하거나 상대적으로 느려질 수 있습니다. 이 경우 계속 작동하는 장식/정렬/장식 취소 접근 방식은 다음과 같습니다.

nl -w1 -s, file |       # Decorate by prefixing with line numbers
sort -ut, -k2,2 |       # Sort uniquely by the real key field
sort -nt, -k1,1 |       # Sort whats left by the line numbers we added
cut -d, -f2-            # Undecorate by removing the line numbers

관련 정보