awk如何获取多列的累计总和?

awk如何获取多列的累计总和?

我有一个管道分隔的文件,例如:

KALPESH|100|200|300
KALPESH|200|300|400
KALPESH|300|400|500
KALPESH|400|500|600

我在用:

awk -F"|" '{ name[$1]+=$2 } END { for (c in name) print c"|"name[c] }' earning1

这给出了第 2 列的结果,例如:

KALPESH|1000

我必须对每一列执行此操作,然后使用join命令但我想要所有 3 列的累积总数,例如:

KALPESH|1000|1400|1800

这可以通过单个 awk 实现吗?

答案1

对于这样的任务,我更喜欢更专业的工具,例如datamash

$ datamash -t '|' -g 1 sum 2 sum 3 sum 4 < file
KALPESH|1000|1400|1800

csvsql工具来自csvkit

$ csvsql -H -d'|' --query '
    select a,sum(b),sum(c),sum(d) from file group by a' file | csvformat -D'|'

a|sum(b)|sum(c)|sum(d)
KALPESH|1000|1400|1800

答案2

我会选择@plumo,并且datamash作为一项规则,但坚持OP请求awk并假设KALPESH有一个朋友,RAJESH所以输入文件是

KALPESH|100|200|300
KALPESH|200|300|400
RAJESH|300|400|500
RAJESH|400|500|599
KALPESH|300|400|500
KALPESH|400|500|600
RAJESH|100|200|300
RAJESH|200|300|400

然后

awk -F\| '{
    flds=(NF>flds)?NF:flds; 
    nm[$1]=$1;
    for (f=2; f<=NF; f++) sum[$1"|"f]+=$f
  }END{
    for (n in nm) {printf "%s", n;
      for (f=2; f<=flds; f++) printf "%s", FS sum[n"|"f]; print""
  }
}' file

KALPESH|1000|1400|1800
RAJESH|1000|1400|1799

如果KALPESH是单独的并且字段的数量是恒定的,那么这会崩溃为

awk -F\| '{
    for (f=2; f<=4; f++) sum[f]+=$f
  }END{
    printf "%s", "KALPESH";
      for (f=2; f<=4; f++) printf "%s", FS sum[f]; print""
  }' file

或者甚至到

awk -F\| '{s2+=$2; s3+=$3; s4+=$4}END{print "KALPESH" FS s2 FS s3 FS s4}' file

答案3

我也这么认为。在不太了解 awk 的情况下,您可以通过使用变量跟踪第二列的总数来在正文中执行此操作姓名可以扩展以计算所有列的总计。给出一个想法:尝试一下,然后根据您的需求进行调整

awk -F"|" '{ total1 += $2; total2 += $3} END { print (total1, total2); }' earnings

目前尚不清楚您到底想要什么:第 1 列的内容重要吗?所有发生的事件是否应该有一个总数,还是总是相同?解决方案取决于此类事情。当您遇到困难时,请告诉我们。

相关内容