Linux

在命令行和腳本上使用 awk 進行重複數據刪除

  • October 24, 2021

我有一個具有以下格式的文件:

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

如您所見,它是一個逗號分隔的文本,帶有重複項。我想使用awk.

命令行

如果我使用 shell 介面,這就是我得到的

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]++}
}

我沒有得到任何輸出。劇本有問題嗎?為什麼腳本和命令行之間的行為不同?

在大括號之外,!a[$1]++是一個條件{print},如果它評估為真(非零),它將觸發預設操作。

在大括號內,{{!a[$1]++}}是一個無條件評估且沒有副作用的*操作。*取下大括號:

#!/bin/awk -f

BEGIN {
   FS=","
}

!a[$1]++

@steeldriver 的 awk 答案是正確的,可能是您所需要的,但是如果您的輸入變得龐大,它可能會耗盡記憶體和/或變得相對較慢,在這種情況下,這裡有一個可以繼續工作的裝飾/排序/取消裝飾方法:

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

引用自:https://unix.stackexchange.com/questions/674638