Awk

計算 awk(或 perl)中的唯一關聯值

  • January 19, 2022

我已經找到“如何列印第 1 列中唯一值出現的增量計數”,這與我的問題類似,但答案不足以滿足我的目的。

首先讓我說明一下我想做的事情:

# Example input
apple   abc jkl
apple   xyz jkl
apple   abc xyz
apple   qrs xyz
apple   abc jkl
banana  abc lmno
banana  lmnop   xyz
banana  lmnopq  jkl
banana  abc jkl
banana  lmnop   pqrs
banana  abcdefg tuv
cucumber    abc lmno
cucumber    abc jkl
cucumber    abc xyz
cucumber    abcd    jkl
cucumber    abc jkl
cucumber    abc lmno

# Desired output
apple   3   2
banana  4   5
cucumber    2   3

因此,對於欄位 1 的每個單獨值,列印該欄位,以及欄位 2 和欄位 3 的唯一關聯值的計數。

輸入按第一個欄位排序,但不允許按其他欄位排序(並且沒有好處,因為第二個和第三個欄位都需要處理)。

我寧願在awk; 在 perl 中它可能要容易得多,我也有興趣學習如何做到這一點,但我正在處理一個 awk 腳本,我寧願不重寫整個事情。

我想出了一種可行的方法*,但是很長,對我來說似乎很hacky。我會將其作為答案發布(當我回到辦公室時),但希望看到任何真正好的*方法。(我不認為我的“好”。)

awk

awk 'function p(){print l,c,d; delete a; delete b; c=d=0} 
 NR!=1&&l!=$1{p()} ++a[$2]==1{c++} ++b[$3]==1{d++} {l=$1} END{p()}' file

解釋:

  • function p(): 定義了一個名為 的函式p(),它列印值並刪除使用的變數和數組。
  • NR!=1&&l!=$1如果它不是第一行並且變數 l 等於第一個欄位$1,則執行該p()函式。
  • ++a[$2]==1{c++}``a如果索引數組的元素值的增量$2等於1,則首先看到該值,因此增加c變數。在++元素之前,返回新值,因此在與 比較之前導致增量1
  • ++b[$3]==1{d++}與上面相同,但具有第三個欄位和d變數。
  • {l=$1}``l到第一個欄位(用於下一次迭代.. 上面)
  • END{p()}處理完最後一行後,awk必須列印最後一個塊的值

根據您給定的輸入,輸出為:

apple 3 2
banana 4 5
cucumber 2 3

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