[英]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.