如何通过Linux命令行合并CSV行并回填空值?
用Linux命令行合并CSV重复行并回填空值
针对你描述的CSV处理需求(按固定列分组,合并同组行并回填可变列的空值),可以用awk实现原生命令行解决方案,无需额外安装工具,适合处理大型文件。
核心思路
以前两列(固定列)为分组键,遍历所有行:
- 对每个分组,保留固定列的值
- 对可变列,用同组内非空值覆盖空值,最终每组输出一行完整数据
具体实现(适配你提供的示例格式)
假设你的CSV分隔符是|(如果是逗号,将脚本中的FS = OFS = "|"改为FS = OFS = ","),创建awk脚本文件merge_csv.awk:
BEGIN { FS = OFS = "|" header_printed = 0 } # 输出表头 NR == 1 { print $0 header_printed = 1 next } # 输出分隔线(示例中的第二行,无此结构可删除该块) NR == 2 { print $0 next } # 处理数据行,按前两列分组存储 { key = $1 FS $2 # 保留固定列 data[key][1] = $1 data[key][2] = $2 # 处理可变列,用非空值更新分组数据 for (i = 3; i <= NF; i++) { if ($i ~ /[^[:space:]]/) { # 判断当前列是否为非空(非空白字符) data[key][i] = $i } else if (!(i in data[key])) { data[key][i] = $i # 初始为空值,后续同组非空值会覆盖 } } } # 输出所有合并后的行 END { for (key in data) { line = data[key][1] for (i = 2; i <= NF; i++) { line = line OFS data[key][i] } print line } }
使用命令
执行以下命令处理输入文件input.csv,输出到output.csv:
awk -f merge_csv.awk input.csv > output.csv
也可以直接用单行命令(省略脚本文件):
awk 'BEGIN{FS=OFS="|"} NR==1{print;next} NR==2{print;next} {key=$1 FS $2; data[key][1]=$1; data[key][2]=$2; for(i=3;i<=NF;i++){if($i~/[^[:space:]]/) data[key][i]=$i; else if(!(i in data[key])) data[key][i]=$i}} END{for(key in data){line=data[key][1]; for(i=2;i<=NF;i++) line=line OFS data[key][i]; print line}}' input.csv > output.csv
注意事项
- 分隔符适配:如果你的CSV用逗号或其他分隔符,修改
FS和OFS的值即可 - 空值格式:若空值是带引号的
"",将判断条件$i ~ /[^[:space:]]/改为$i != "\"\"" - 性能:awk处理大型CSV的效率较高,内存占用取决于分组数量,适合大多数场景
内容的提问来源于stack exchange,提问作者Vladislavs Dovgalecs
相关产品推荐
相关产品推荐

