我有一个包含两列(140万行)的文件,如下所示:
CLM MXL
0 0
0 1
1 1
1 1
0 0
29 42
0 0
30 15
我想计算每种可能的价值组合的实例;例如,如果有列数CLM等于0且列MXL与1匹配的行数为x,我想打印:
0 1 x
由于列CLM的最大值为188且列MXL的最大值为128,我试图在awk中使用嵌套的for循环,如下所示:
awk '{for (i=0; i<=188; i++) {for (j=0; j<=128; j++) {if($9==i && $10==j) {print$0}}}}' 1000Genomes.ALL.new.txt > test
但这只打印出原始文件,这是有意义的,我只是不知道如何正确编写for循环,为每个值组合打印出一个文件,然后我可以wc,或打印出一个每个组合的计数文件。在awk,bash脚本,perl脚本中的任何解决方案都会很棒。
答案 0 :(得分:3)
awk
解决方案$ awk 'NR>1{c[$0]++} END{for (k in c)print k,c[k]}' file | sort -n
0 0 3
0 1 1
1 1 2
29 42 1
30 15 1
代码使用单个变量c
。 c
是一个关联数组,其键是文件中的行,其值是出现的次数。
NR>1{c[$0]++}
对于除第一行(具有标题)之外的每一行,这会增加该行中组合的计数。
END{for (k in c)print k,c[k]}
这将打印出最终的计数。
sort -n
这只是为了美学:它以可预测的顺序输出输出线。
uniq -c
$ tail -n+2 file | sort -n | uniq -c | awk '{print $2,$3,$1}'
0 0 3
0 1 1
1 1 2
29 42 1
30 15 1
tail -n+2 file
这将打印除文件第一行以外的所有行。这样做的目的是删除列标题。
sort -n | uniq -c
对行进行排序,然后对重复项进行计数。
awk '{print $2,$3,$1}
uniq -c
将计数放在首位,您希望计数成为最后一项。这只是将列重新排列为您想要的格式。