我有一个管道分隔的文件,例如:
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 列的内容重要吗?所有发生的事件是否应该有一个总数,还是总是相同?解决方案取决于此类事情。当您遇到困难时,请告诉我们。