根据第一列对所有行进行分组,然后计算第二列和第三列的总和

根据第一列对所有行进行分组,然后计算第二列和第三列的总和

我需要根据第一列对行进行分组,然后计算所有第二行的值的总和以及所有第三行的值的总和。

第二列应计算如下:10:56 = 10*60 + 56 = 656 秒。

输入文件:

     testing 00:34 123487
     archive 00:45 3973
     testing 09:16 800500
     archive 10:10 100000

输出:

     archive 655 103973
     testing 590 923987

答案1

打高尔夫球时只打出一杆。在 GNU awk 3.1.7 上运行良好。其他 awk 实现可能需要$2*60替换为substr($2,0,2)*60. (期望“09:16”之类的内容被解释为整数值 9 稍微扩展了规则。)

awk '{a[$1]+=$2*60+substr($2,4);b[$1]+=$3}END{for(c in a){print c,a[c],b[c]}}'

给出输出:

archive 655 103973
testing 590 923987

或者,perl 方法:

perl -e 'while(<>){/(\S+) +(\d+):(\d+) (\d+)/;$a{$1}+=$2*60+$3;$b{$1}+=$4;}for(keys %a){print "$_ $a{$_} $b{$_}\n"}'

答案2

使用此awk脚本gawk

{
   split($2,time,":");
   seconds=time[1]*60;
   seconds+=time[2];
   types[$1]["time"]+=seconds;
   types[$1]["othersum"]+=$3
}

END {
   for (record in types)
      print record, types[record]["time"], types[record]["othersum"]
}

gawk -f script.awk /path/to/input似乎可以解决问题。

如果你需要它作为单行,你可以这样做:

gawk '{split($2,time,":");seconds=time[1]*60;seconds+=time[2];types[$1]["time"]+=seconds;types[$1]["othersum"]+=$3} END {for (record in types) print record, types[record]["time"], types[record]["othersum"] }' /path/to/input

答案3

只为多样化

perl -pe 's/(\d+):(\d+)/60*$1+$2/e' file | datamash -Ws groupby 1 sum 2,3
archive 655     103973
testing 590     923987

相关内容