如何用awk按制表符文件首列值合并指定列值为逗号分隔列表
按首列分组拼接指定列的awk实现
需求说明
处理制表符分隔的文本文件,规则如下:
- 以第1列的取值为分组维度
- 同组内的第2、4、5列值,按原始出现顺序拼接为逗号分隔的列表,保留重复值
- 同组内第3列值固定,直接保留
- 最终输出列之间仍用制表符分隔,保持和原文件一致的列顺序
原有命令仅提取全文件第2列做全局换行替换,没有分组判断逻辑,因此无法按首列的不同取值分别聚合结果,原命令如下:
awk -F"\t" '{print $2}' $i | sed -z 's/\n/,/g;s/,$/\n/'
测试样例
输入文件内容(制表符分隔):
Bob 24 M apples red Bob 12 M apples green Linda 56 F apples red Linda 102 F bananas yellow
期望输出:
Bob 24,12 M apples,apples red,green Linda 56,102 F apples,bananas red,yellow
可用命令
直接用awk单命令就能实现全流程,不需要额外接sed处理,核心逻辑是通过数组记录每个分组的拼接值,同时记录分组首次出现的顺序,保证输出顺序和原文件一致:
awk -F'\t' ' !seen[$1]++ { order[++cnt] = $1 c2[$1] = $2 c3[$1] = $3 c4[$1] = $4 c5[$1] = $5 next } { c2[$1] = c2[$1] "," $2 c4[$1] = c4[$1] "," $4 c5[$1] = c5[$1] "," $5 } END { for (i=1; i<=cnt; i++) { cur = order[i] printf "%s\t%s\t%s\t%s\t%s\n", cur, c2[cur], c3[cur], c4[cur], c5[cur] } } ' 待处理文件路径
把命令里的待处理文件路径替换成实际文件路径即可,传入上述样例输入时输出和预期完全一致,会保留所有重复值、遵循原始出现顺序。
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

