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