我有这样的文件:
1 UA
2 GB
3 UA
3 UA
2 US
1 UA
4 US
如何按第二列分组并按第一列求和?所以输出应该是这样的:
8 UA
6 US
2 GB
答案1
和GNU awk
:
$ awk 'BEGIN{PROCINFO["sorted_in"] = "@val_num_desc"}
{a[$2]+=$1} END{for(k in a) print a[k], k}' ip.txt
8 UA
6 US
2 GB
看gawk 手册:使用预定义的数组扫描顺序有关排序选项的详细信息。
和perl
:
perl -lane '$h{$F[1]}+=$F[0]; END{print "$h{$_} $_" for
sort {$h{$b} <=> $h{$a}} keys %h}' ip.txt
答案2
使用 GNU datamash
:
$ datamash -W -s -g 2 sum 1 <file
GB 2
UA 8
US 6
这会将空格视为字段分隔符,对第二个字段上的输入进行排序,在此字段上对其进行分组,并对每个组的第一个字段求和。
awk '{ print $2, $1 }'
如果您想交换列(datamash
始终在其输出中首先写入分组列),并且sort -nr
如果您想按示例中的降序对输出进行排序,则通过管道传输输出:
$ datamash -W -s -g 2 sum 1 <file | awk '{ print $2, $1 }' | sort -nr
8 UA
6 US
2 GB
用于awk
求和:
$ awk '{ sum[$2] += $1 } END { for (i in sum) print sum[i], i }' file
8 UA
2 GB
6 US
sort -nr
如上所述,将其传递给排序。