Uniq

計算 2 行塊的 uniq 實例

  • December 15, 2017

給定輸入:

144.252.36.69
afrloop=32235330165603
144.252.36.69
afrloop=32235330165603
144.252.36.69
afrloop=32235330165603
222.252.36.69
afrloop=31135330165603
222.252.36.69
afrloop=31135330165603
222.252.36.69
afrloop=31135330165603
222.252.36.69
afrloop=31135330165603

我怎樣才能輸出:

144.252.36.69
afrloop=32235330165603 3 times
222.252.36.69
afrloop=31135330165603 4 times
paste - - < file | sort | uniq -c

awk如果您想要自定義輸出格式,這是一個解決方案

NR%2==1 {ip=$0; next}
NR%2==0 {a[ip"\n"$0]++}
END {
   for(i in a)
       printf "%s %d times\n", i, a[i]
}

該腳本可以執行為

awk -f main.awk file

解釋

  • 首先,我們使用NR%2==1匹配奇數行,因為奇數模 2 等於 1,如果任何行匹配此條件,則我們將整行保存$0到名為 的變數ip中。我們可以使用next跳過任何進一步的處理並直接進行下一次迭代。
  • 其次,我們NR%2==0用來匹配偶數行,如果一行匹配,那麼我們創建一個標記為ip"\n"$0數組的索引,a並增加該特定索引的計數值。例如,等效的擴展就像
a["144.252.36.69 afrloop=32235330165603"] += 1

為了簡單起見,我忽略了\n此範例中的新行

  • 最後END,在處理完每一行之後,我們使用for循環列印出數組中每個元素的值a,在我們的例子中是每個唯一索引的計數

有趣的基準

  • 測試文件生成(100 萬條記錄)
awk '
   BEGIN{for(i=1;i<10000000;i++)
   printf "%d\nafrLoop=%d\n", int(rand()*100), int(rand()*10)}
' > test

$ head test
23
afrLoop=2
84
afrLoop=1
58
  • @n.caillou 粘貼解決方案
$ time paste - - < test | sort | uniq -c > /dev/null
real    0m11.250s
user    0m11.352s
sys     0m0.272s
  • awk 解決方案
$ time awk -f main.awk test > /dev/null
real    0m5.673s
user    0m5.636s
sys     0m0.036s

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