我经常使用sort | uniq -c
来计算统计数据。
现在,如果我有两个带有这种计数统计数据的文件,我想将它们放在一起并添加计数。 (我知道我可以附加原始文件并在那里计算,但我们假设只有计数文件可以访问)。
例如:
a.cnt:
1 a
2 c
b.cnt:
2 b
1 c
我想连接并得到以下输出:
1 a
2 b
3 c
在shell中执行此操作的最短方法是什么?
修改
感谢目前为止的答案!
可能需要另外考虑的一些可能的方面:
sort | uniq -c
- 样式命令行选项,一次只能查看两行?答案 0 :(得分:8)
这适用于任何给定数量的文件:
$ cat a.cnt b.cnt | awk '{a[$2]+=$1} END{for (i in a) print a[i],i}'
1 a
2 b
3 c
因此,如果您让我们说出10个文件,您只需执行cat f1 f2 ...
然后管道awk
。
如果文件名碰巧共享一个模式,你也可以(thanks Adrian Frühwirth!):
awk '{a[$2]+=$1} END{for (i in a) print a[i],i}' *cnt
例如,这将考虑所有扩展名为cnt
的文件。
可能需要另外考虑的一些可能的方面:
- 如果a,b,c是包含任意空格的arbritrary字符串怎么办?
- 如果文件太大而无法放入内存怎么办?这种情况下是否有一些
sort | uniq -c
- 样式命令行选项,一次只能查看两行?
在这种情况下,您可以使用其余列作为计数器的索引:
cat *cnt | awk '{count=$1; $1=""; a[$0]=count} END{for (i in a) print a[i],i}'
请注意,实际上您不需要sort | uniq -c
并重定向到cnt
文件,然后执行此重新计数。你可以这样做:
awk '{a[$0]++} END{for (i in a) print a[i], i}' file
$ cat a.cnt
1 and some
2 text here
$ cat b.cnt
4 and some
4 and other things
2 text here
9 blabla
$ cat *cnt | awk '{count=$1; $1=""; a[$0]=count} END{for (i in a) print a[i],i}'
2 text here
9 blabla
4 and some
4 and other things
关于第二条评论:
$ cat b
and some
text here
and some
and other things
text here
blabla
$ awk '{a[$0]++} END{for (i in a) print a[i], i}' b
2 and some
2 text here
1 and other things
1 blabla
答案 1 :(得分:5)
使用awk:
awk 'FNR==NR{a[$2]=$1;next} $2 in a{a[$2]+=$1}1' a.cnt b.cnt
1 a
2 b
3 c
答案 2 :(得分:5)
$ awk '{a[$2]+=$1}END{for(i in a){print a[i], i}}' a.cnt b.cnt
1 a
2 b
3 c