我正在尝试对第2列中的某些数字求和,它可以与我的代码一起使用。但是我还想计算在第2列中重复相同的值并打印在最后一列中的次数。
文件1
36 2605 1 2
36 2605 1 2
36 2603 1 2
36 2605 1 2
36 2605 1 2
36 2605 1 2
36 2606 1 2
所需的输出
2603 36 1 2 1
2605 180 5 10 5
2606 36 1 2 1
我尝试过
awk '{a[$2]+=$1}{b[$2]+=$3}{c[$2]+=$4;count[$2]+=$2}END{for(i in a)print i,a[i],b[i],c[i],count[i]}' file1
预先感谢
答案 0 :(得分:5)
重命名了vars,并添加了漂亮的印刷品:
awk '
{
sum1[$2]+=$1
sum3[$2]+=$3
sum4[$2]+=$4
count[$2]++
len2=((l=length($2))>len2?l:len2)
len1=((l=length(sum1[$2]))>len1?l:len1)
len3=((l=length(sum3[$2]))>len3?l:len3)
len4=((l=length(sum4[$2]))>len4?l:len4)
len5=((l=length(sum5[$2]))>len5?l:len5)
}
END {
for(i in count) {
printf "%*d %*d %*d %*d %*d\n",
len2,i,len1,sum1[i],len3,sum3[i],len4,sum4[i],len5,count[i]
}
}' file
输出:
2603 36 1 2 1
2605 180 5 10 5
2606 36 1 2 1
答案 1 :(得分:4)
这些天来,太空字符相对便宜,您应该真正考虑为代码获取一些,特别是如果您希望其他人阅读它来帮助您调试它的话!这是您发布的代码:
awk '{a[$2]+=$1}{b[$2]+=$3}{c[$2]+=$4;count[$2]+=$2}END{for(i in a)print i,a[i],b[i],c[i],count[i]}' file1
这里是经过代码美化程序(我使用过gawk -o
)之后的情况:
{
a[$2] += $1
}
{
b[$2] += $3
}
{
c[$2] += $4
count[$2] += $2
}
END {
for (i in a) {
print i, a[i], b[i], c[i], count[i]
}
}
看看如何通过添加一些空格现在变得非常容易理解,因此如何显着填充count[$2]
的错误是显而易见的?一些有意义的变量名称也总是非常有用,而且我听说字母数字字符现在很特殊!
FWIW这是我的处理方式:
$ cat tst.awk
BEGIN { keyFldNr = 2 }
{
numOutFlds = 0
for (i=1; i<=NF; i++) {
if (i != keyFldNr) {
sum[$keyFldNr,++numOutFlds] += $i
}
}
cnt[$keyFldNr]++
}
END {
for (key in cnt) {
printf "%s%s", key, OFS
for (i=1; i<=numOutFlds; i++) {
printf "%s%s", sum[key,i], OFS
}
print cnt[key]
}
}
$ awk -f tst.awk file
2603 36 1 2 1
2605 180 5 10 5
2606 36 1 2 1
$ awk -f tst.awk file | column -t
2603 36 1 2 1
2605 180 5 10 5
2606 36 1 2 1
请注意,无论您每行有多少个字段,它都将按原样运行,如果您需要对要使用的键使用不同的字段进行计数和求和,则只需更改以下字段中的keyFldNr值即可:从2开始,直到您想要的任何部分。
答案 2 :(得分:3)
您几乎钉牢了,您没有适当地增加count[$2]
。
$ awk '{a[$2]+=$1;b[$2]+=$3;c[$2]+=$4;count[$2]++}
END{for(i in a) print i,a[i],b[i],c[i],count[i]}' file
2603 36 1 2 1
2605 180 5 10 5
2606 36 1 2 1
答案 3 :(得分:2)
使用非常有用的GNU datamash的非笨拙方法,该方法专为此类任务而设计:
$ datamash -Ws groupby 2 sum 1,3,4 count 2 < input.txt
2603 36 1 2 1
2605 180 5 10 5
2606 36 1 2 1
读取为:对于第2列中具有相同值的每组行,显示该值,第1、3和4列的总和以及该组中的行数。
答案 4 :(得分:2)
不需要外部程序,速度更快〜21ms,可以在纯gnu awk上尝试
awk '{if($0~/^[A-Za-z0-9]/)a[NR]=$2" "$1" "$3" "$4}END{asort(a);$0="";for(;i++<NR;){split(a[i],b);if($1==""||b[1]==$1){$2+=b[2];$3+=b[3];$4+=b[4];$5++} else {print;$2=b[2];$3=b[3];$4=b[4];$5=1} $1=b[1]} print}' file1