others - awk - 合计列和计数行

我试图在 2列中求和,它与我的代码一起工作。 但我想计算 colum 2中相同值重复多少次并在最后一列中打印 。

file1


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



先谢谢了

时间:

重命名了var并添加了漂亮的打印:


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 %*dn",


 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



如今,空间字符相对便宜你应该考虑为你的代码获取一些代码,特别是如果你希望其他人阅读它以帮助你调试它 以下是你发布的代码:


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]


 }


}



看看如何通过添加一些空白区域它现在更容易理解,所以 Bug 如何填充 count[$2] 是明显的 glaringly 一些有意义的变量名总是非常有用,我听说字母数字字符现在是特殊的 !

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更改为无论你想要什么 。

一个非awk方法,使用非常有用的 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的总和,以及组中的行数

...