如何根据 2 列合并和求和字段

如何根据 2 列合并和求和字段

我有一个文件如下:

Bitrate        ASNUM       TotalBytes    DownloadTime   NumberCount

280000          2856        61454           12

280000          2856        61428           14

1179968         2856        309430          11

1179968         4156        309200          15

4864960         2856        997962          193 

4864960         2856        1115576         300

4864960         2856        997962          116

我需要根据前 2 列(即比特率和 ASNUM)合并行,并将与它们相对应的总字节数和下载时间字段相加。

结果输出应如下所示:

Bitrate        ASNUM      TotalBytes     DownloadTime   NumberCount 

280000          2856        122882          26               2  

1179968         2856        309430          11               1

1179968         4156        309200          15               1

4864960         2856        3111500         609              3  

其中附加列 NumberCount 指示出现的次数。

您能否帮助我实现可以实现此功能的代码?

答案1

这是使用 awk 的解决方案:

awk -F " " '
    NR==1 {print; next} 
    NF {a[$1" "$2]+=$3; b[$1" "$2]+=$4; c[$1" "$2]++} 
    END {for(i in a)print i, a[i], b[i], c[i]}
' file

--> inputFile 应该位于运行命令的目录中

--> -F " " 认为单个空格作为分隔符

--> NR==1{print;next} 打印要输出的标题并跳过它

--> 数组 a[$1" "$2] 考虑第一列值和第二列值的分组依据。数组 b 和 c 相同。

--> += 运算符根据数组的分组依据对所需列进行求和

--> 与数组 c 一起使用的 ++ 运算符存储 group by 的计数

--> 最后一个“for”循环用于打印结果以输出

答案2

GNU 数据混合是为此类任务而设计的 - 例如

datamash -WH -g 1,2 sum 3,4 count 4

或者更详细地说

datamash --whitespace --headers \
  groupby Bitrate,ASNUM sum TotalBytes,DownloadTime count DownloadTime

(您为 指定哪个非分组字段并不重要count)。

您的情况因空白行而稍微复杂 - 但您可以简单地在之前将它们删除并在之后重新添加它们,例如

sed '/^$/d' file | datamash -WH -g 1,2 sum 3,4 count 4 | column -t | sed G
GroupBy(Bitrate)  GroupBy(ASNUM)  sum(TotalBytes)  sum(DownloadTime)  count(DownloadTime)

280000            2856            122882           26                 2

1179968           2856            309430           11                 1

1179968           4156            309200           15                 1

4864960           2856            3111500          609                3

相关内容