给定此输入表:
pac1 xxx
pac1 yyy
pac1 zzz
pac2 xxx
pac2 uuu
pac3 zzz
pac3 uuu
pac4 zzz
Run Code Online (Sandbox Code Playgroud)
我需要将频率添加到第三列,如下所示:
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
Run Code Online (Sandbox Code Playgroud)
第一个数字是第二列中出现的次数.
awk '{print $2}' input | sort | uniq -c
Run Code Online (Sandbox Code Playgroud)
斜杠后的数字是第一列的单独出现:
awk '{print $1}' input | sort | uniq -c
Run Code Online (Sandbox Code Playgroud)
我想在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
Run Code Online (Sandbox Code Playgroud)
所以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
Run Code Online (Sandbox Code Playgroud)
A想避免变量$出现.
只需读取文件两次:首先计算值并将它们存储在一个数组中,然后打印它的值:
$ 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
Run Code Online (Sandbox Code Playgroud)
这FNR==NR {things; next}是在阅读第一个文件时做的事情.它基于使用FNR和NR:前者表示记录的字段数和后面的记录数.这意味着FNR包含当前文件的行数,而NR包含到目前为止已读取的行数,FNR==NR在读取第一个文件时生效.通过添加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
Run Code Online (Sandbox Code Playgroud)