第一列中相同值的第二列和第三列之和

时间:2019-04-23 07:41:59

标签: linux shell awk sed scripting

我想将第2列和第3列中的值求和为第1列中的相同值

1555971000 6 1   
1555971000 0 2  
1555971300 2 0  
1555971300 3 0 

输出就像

1555971000 6 3  
1555971300 5 0 

我已经尝试过以下命令

awk -F" " '{b[$2]+=$1} END { for (i in b) { print b[i],i } } '

但这似乎仅用于一列。

5 个答案:

答案 0 :(得分:1)

这是另一种读取Input_file两次的方式,它将以与Input_file的顺序相同的顺序提供输出。

awk 'FNR==NR{a[$1]+=$2;b[$1]+=$3;next} ($1 in a){print $1,a[$1],b[$1];delete a[$1]}' Input_file Input_file

答案 1 :(得分:1)

如果'd'中的数据没有排序,请尝试使用gnu awk,

awk 'BEGIN{f=1} {if($1==a||f){b+=$2;c+=$3;f=0} else{print a,b,c;b=$2;c=$3} a=$1} END{print a,b,c}' d

与排序gnu awk

awk '{w[NR]=$0} END{asort(w);f=1;for(;i++<NR;){split(w[i],v);if(v[1]==a||f){f=0;b+=v[2];c+=v[3]} else{print a,b,c;b=v[2];c=v[3];} a=v[1]} print a,b,c;}' d

答案 2 :(得分:0)

您可以使用awk进行操作,方法是先将字段保存在第一条记录中,然后对于所有后续记录,比较第一个字段是否匹配,如果匹配,则添加两个和三个字段的内容,然后继续。如果第一个字段不匹配,则输出您的第一个字段和运行总和,例如

awk '{ 
    if ($1 == a) { 
        b+=$2; c+=$3; 
    }
    else {
        print a, b, c; a=$1; b=$2; c=$3;
    }
} END { print a, b, c; }' file

file中输入内容后,您可以将上述内容复制并粘贴到您的终端中并获得以下内容:

使用/输出示例

$ awk '{
>     if ($1 == a) {
>         b+=$2; c+=$3;
>     }
>     else {
>         print a, b, c; a=$1; b=$2; c=$3;
>     }
> } END { print a, b, c; }' file

1555971000 6 3
1555971300 5 0

使用awk数组

使用不需要您的输入按排序顺序排列的数组的更简短简洁的选择是:

awk '{a[$1]+=$2; b[$1]+=$3} END{ for (i in a) print i, a[i], b[i] }' file

(相同的输出)

如果您的数据文件以随机顺序包含以下几行,例如,使用数组可以使像field1这样的列的总和同样有效,例如

1555971300 2 0
1555971000 0 2
1555971000 6 1
1555971300 3 0

答案 3 :(得分:0)

另一个awk不管记录的顺序如何,无论它们是否未排序,都可以使用:

awk '{r[$1]++}
     r[$1]==1{o[++c]=$1}
     {f[$1]+=$2;s[$1]+=$3}
     END{for(i=1;i<=c;i++){print o[i],f[o[i]],s[o[i]]}}' file

答案 4 :(得分:0)

假设您写的时间:

awk -F" " '{b[$2]+=$1} END { for (i in b) { print b[i],i } } '

您打算写:

awk '{ b[$1]+=$2 } END{ for (i in b) print i,b[i] }'

弄清楚这不是一个巨大的飞跃:

$ awk '{ b[$1]+=$2; c[$1]+=$3 } END{ for (i in b) print i,b[i],c[i] }' file
1555971000 6 3
1555971300 5 0

请获取Arnold Robbins的第4版“有效的Awk编程”,并阅读有关字段和数组的第1或第2段。