我有一個包含兩列和 1000 萬行的文件。第一列包含許多重複值,但第 2 列中有一個不同的值awk
。注意:文件依第 1 列的值排序。
1.123 -4.0
2.234 -3.5
2.234 -3.1
2.234 -2.0
4.432 0.0
5.123 +0.2
8.654 +0.5
8.654 +0.8
8.654 +0.9
.
.
.
.
預期產出
1.123 -4.0
2.234 -3.5
4.432 0.0
5.123 +0.2
8.654 +0.5
.
.
.
.
答案1
幾個方法:
awk
awk '!a[$1]++' file
這是一種非常簡潔的寫法:
awk '{if(! a[$1]){print; a[$1]++}}' file
因此,如果目前第一個欄位 (
$1
) 不在a
陣列中,則列印該行並將第一個欄位新增至a
。下次我們看到該欄位時,它將位於數組中,因此不會被列印。珀爾
perl -ane '$k{$F[0]}++ or print' file
或者
perl -ane 'print if !$k{$F[0]}++' file
這個和上一個基本上是一樣的
awk
。這-n
導致 perl 逐行讀取輸入檔並將提供的腳本應用-e
到每一行。將-a
自動在空白處分割每一行並將結果欄位儲存在@F
陣列中。最後,將第一個欄位新增至%k
哈希中,如果尚不存在,則列印該行。同樣的事情可以寫成perl -e 'while(<>){ @F=split(/\s+/); print unless defined($k{$F[0]}); $k{$F[0]}++; }' file
核心工具
rev file | uniq -f 1 | rev
此方法的工作原理是首先反轉行,這樣如果行是 12 345,那麼現在
file
將是 543 21uniq -f 1
。此處file
使用的uniq
效果是過濾掉任何重複的行,每行僅保留 1 個。最後,我們透過另一個相反的操作將線條恢復到原來的順序。GNU 排序(如建議作者:@StéphaneChazelas)
sort -buk1,1
此
-b
標誌忽略前導空格,且此-u
方法僅列印唯一欄位。聰明的一點是-k1,1
.此-k
標誌設定要排序的欄位。它採用通用格式,即排序時-k POS1[,POS2]
只透過POS2查看字段。POS1
所以,-k1,1
意味著只看第一個字段。根據您的數據,您可能還想添加以下選項之一:-g, --general-numeric-sort compare according to general numerical value -n, --numeric-sort compare according to string numerical value
答案2
如果第一列始終為 5 個字元長,您可以簡單地使用uniq
:
uniq -w 5 file
如果沒有,請使用awk
:
awk '$1!=a{print $0; a=$1}' file
對於大文件,第一個肯定會更快。