[英]Add frequency (number of occurrences) to my table of text through awk
給定此輸入表:
pac1 xxx
pac1 yyy
pac1 zzz
pac2 xxx
pac2 uuu
pac3 zzz
pac3 uuu
pac4 zzz
我需要向第三列添加頻率,如下所示:
pac1 xxx 2/3
pac1 yyy 1/3
pac1 zzz 3/3
pac2 xxx 2/2
pac2 uuu 2/2
pac3 zzz 2/2
pac3 uuu 2/2
pac4 zzz 3/1
其中第一個數字是第二列中的出現次數。
awk '{print $2}' input | sort | uniq -c
而斜線后的數字是第一列的唯一性出現:
awk '{print $1}' input | sort | uniq -c
我想在awk中使用實現。
編輯:
請修改輸出-第一列是名稱,我需要計算第一列中出現了多少個uniq名稱,例如:
pac1 xxx 2/4
pac1 yyy 1/4
pac1 zzz 3/4
pac2 xxx 2/4
pac2 uuu 2/4
pac3 zzz 2/4
pac3 uuu 2/4
pac4 zzz 3/4
所以uniq名稱只有pac1,pac2,pac3,pac4 => 4
像這樣:
occur=$(awk '{print $1}' input | sort | wc -l)
awk -v occur=$occur '{col2[$2]++} {print $0, col2[$2] "/" occur}' file
A希望避免變量$ occur。
只需讀取文件兩次:首先計算值並將它們存儲在數組中,然后打印其值:
$ awk 'FNR==NR {col1[$1]++; col2[$2]++; next} {print $0, col2[$2] "/" col1[$1]}' file file
pac1 xxx 2/3
pac1 yyy 1/3
pac1 zzz 3/3
pac2 xxx 2/2
pac2 uuu 2/2
pac3 zzz 3/2
pac3 uuu 2/2
pac4 zzz 3/1
FNR==NR {things; next}
FNR==NR {things; next}
是僅在讀取第一個文件時執行操作的一種技巧。 它是基於使用FNR
和NR
:前者表示記錄的字段編號,而后者表示記錄的編號。 這意味着FNR包含當前文件的行數,而NR包含到目前為止已整體讀取的行數,這使得FNR==NR
僅在讀取第一個文件時為true。 通過添加next
我們跳過當前行並跳至下一行。
在Idiomatic awk中查找更多信息。
關於更新:如果您希望最后一項在第一列中包含不同值的計數,則只需檢查創建的數組的長度即可。 這將告訴您它包含許多不同的索引,從而告訴您所需的值:
$ awk 'FNR==NR {col1[$1]++; col2[$2]++; next} {print $0, col2[$2] "/" length(col1)}' file file
pac1 xxx 2/4
pac1 yyy 1/4
pac1 zzz 3/4
pac2 xxx 2/4
pac2 uuu 2/4
pac3 zzz 3/4
pac3 uuu 2/4
pac4 zzz 3/4
如果要使用awk
,那么您將需要遍歷每一行,並使用三個關聯數組收集一些信息。 一種收集原始數據,一種統計第2列重復的實例,一種統計第3列重復的實例。 然后,使END { for (item in data_array)}
遍歷數據數組,拆分字段以獲取值以用作其他兩個數組的索引,並以適當的頻率打印每一行。 就像是:
awk '{ data[num++] = $0;
col1[$1]++;
col2[$2]++
}
END { for (i = 0; i < num; i++) {
split(data[i], field)
printf "%s %d/%d\n", data[i], col2[field[2]], col1[field[1]]
}
}' < input.file
這僅需要讀取一次文件,並且可以擴展為其他列和計數。 for
循環使數據按收集時的順序顯示。
看看man awk
對關聯數組的信息,分割字符串,並for
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.