![在Linux中的文件中统一第一列并在第二列中添加数字](https://linux22.com/image/223809/%E5%9C%A8Linux%E4%B8%AD%E7%9A%84%E6%96%87%E4%BB%B6%E4%B8%AD%E7%BB%9F%E4%B8%80%E7%AC%AC%E4%B8%80%E5%88%97%E5%B9%B6%E5%9C%A8%E7%AC%AC%E4%BA%8C%E5%88%97%E4%B8%AD%E6%B7%BB%E5%8A%A0%E6%95%B0%E5%AD%97.png)
我正在从多个文件收集数据并将其转储到单个摘要文件中。
cat *files* | sort -u > final.rpt
a 1
a 5
a 6
b 2
b 3
b 0
c 1
c 7
如何根据第一列中的字符串进行唯一化,并对第二列中与该字符串对应的所有数字求和。对于上面的例子,预期输出是:
a 12
b 5
c 8
答案1
类似的东西可以完成这项工作:
awk '{a[$1]+=$2} END {for (i in a) print i, a[i]}' <input file>
这个想法是使用关联数组并对第二列中的值求和
答案2
使用datamash
:
$ datamash -sW sum 2 -g 1 <file
这将计算sum
第二个字段和groupby
第一个字段。
使用Miller
:
$ mlr --nidx stats1 -a sum -f 2 -g 1 file
假设未排序的文件仅具有两个字段,如下所示:
a 1
a 5
a 6
b 2
b 3
b 0
c 1
c 7
a 1
以下命令首先对文件进行排序,然后计算总和。
$ mlr --nidx uniq -f 1,2 then \
stats1 -a sum -f 2 -g 1 file
答案3
为了完整起见,这里给出了 O(1) 的内存使用解决方案:
awk 'NR>1 && $1!=prev {print prev, sum;sum=0} {sum+=$2;prev=$1} END {print prev, sum}' < final.rpt
a 12
b 5
c 8
解释:对于每条 $1 发生变化的新记录,我们打印结果并重置总和。我们还在文件末尾打印结果,但不在开头(NR>1)。与带有关联数组的版本相比,该代码有些麻烦。
答案4
可以... | sort | uniq -c >final.rpt
(而不是使用... | sort -u >final.rpt
)来收集数据吗?