如何用Awk合并首列与第二列值匹配的行?
使用Awk合并首列与第二列值匹配的行
没问题,这用Awk完全能搞定!我先结合具体的输入/输出示例给你演示两种常见的合并场景,你可以根据自己的需求调整。
场景1:合并后对第三列求和
假设你的输入文件input.txt内容如下(逗号分隔):
apple,red,10 apple,red,20 banana,yellow,15 apple,green,5 banana,yellow,25
预期输出:将前两列完全匹配的行合并,第三列值求和:
apple,red,30 banana,yellow,40 apple,green,5
实现命令
awk -F',' '{key = $1 "," $2; sum[key] += $3} END {for (k in sum) print k "," sum[k]}' input.txt
代码解释
-F',':指定字段分隔符为逗号(如果你的文件是空格/制表符分隔,去掉这个参数即可,Awk默认用空白字符分隔)key = $1 "," $2:把第一列和第二列拼接成唯一标识的键,确保只有两列值都匹配的行才会被归为同一组sum[key] += $3:将当前行第三列的值累加到对应键的总和中END块:处理完所有行后,遍历存储总和的关联数组,输出每个键和对应的累加结果
场景2:合并后拼接第三列的所有值
如果你的需求不是求和,而是把同一组的第三列值拼接在一起,比如用逗号分隔:
预期输出:
apple,red,10,20 banana,yellow,15,25 apple,green,5
实现命令
awk -F',' '{key = $1 "," $2; vals[key] = vals[key] (vals[key] ? "," : "") $3} END {for (k in vals) print k "," vals[k]}' input.txt
代码解释
vals[key] = vals[key] (vals[key] ? "," : "") $3:如果当前键已经有值,就先加个逗号再拼接新值;如果是首次出现,直接赋值,避免开头多一个逗号- 其他部分和场景1逻辑一致
进阶:保持输出顺序与输入中组的首次出现顺序
默认情况下Awk遍历关联数组是无序的,如果想要输出顺序和输入中每组首次出现的顺序一致,可以加一个数组记录顺序:
求和且保序的命令
awk -F',' '{key = $1 "," $2; if (!(key in sum)) order[++n] = key; sum[key] += $3} END {for (i=1; i<=n; i++) print order[i] "," sum[order[i]]}' input.txt
解释
order[++n] = key:当某个键第一次出现时,把它加入到order数组中,记录出现顺序- 最后遍历
order数组而不是直接遍历关联数组,就能保持输入的顺序啦
要是你还有其他特殊需求(比如分隔符不同、需要合并更多列等),随时说,我再帮你调整脚本~
内容的提问来源于stack exchange,提问作者veda sol85
相关产品推荐
相关产品推荐

