You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shell脚本实现多CSV文件基于双主键列合并的技术求助

多CSV文件按主键合并解决方案

我明白你被这个多CSV文件合并的问题困扰好久了,前两列作为主键合并后续字段的需求其实用awk就能很好解决,先说说为什么你之前用join可能没成功,再给你一个靠谱的脚本方案:

为什么join可能没成功?

join命令默认只处理两个文件,而且要求输入文件按主键排序,另外你的文件分隔符是; (分号加空格),join默认用空白字符分隔,如果你没指定-t';'或者处理空格的问题,就会匹配出错。而且要合并5个以上文件的话,需要多次嵌套join,操作起来非常繁琐,这也是你没成功的大概率原因。

用awk实现多文件合并的脚本

awk可以轻松处理任意数量的CSV文件,并且自动按主键关联内容,完全符合你的需求:

基础版脚本(不保留原文件主键顺序)

创建一个名为merge_csv.awk的文件,内容如下:

BEGIN {
    # 设置输入输出的分隔符为你的文件格式:分号加空格
    FS = OFS = "; "
}
{
    # 用前两列拼接成唯一主键
    key = $1 OFS $2
    # 提取当前行从第三列开始的所有内容,作为当前文件对应主键的值
    current_val = ""
    for (i=3; i<=NF; i++) {
        current_val = current_val (current_val ? OFS : "") $i
    }
    # 关联数组存储主键对应的所有值:首次遇到则初始化,否则追加新值
    if (!(key in data)) {
        data[key] = current_val
    } else {
        data[key] = data[key] OFS current_val
    }
}
END {
    # 遍历所有主键,输出合并后的内容
    for (key in data) {
        print key, data[key]
    }
}

保留原文件主键顺序的版本

如果希望合并后的输出顺序和第一个文件中主键出现的顺序一致,可以用下面的版本:

BEGIN {
    FS = OFS = "; "
}
{
    key = $1 OFS $2
    current_val = ""
    for (i=3; i<=NF; i++) {
        current_val = current_val (current_val ? OFS : "") $i
    }
    if (!(key in data)) {
        data[key] = current_val
        # 记录主键首次出现的顺序
        order[++order_count] = key
    } else {
        data[key] = data[key] OFS current_val
    }
}
END {
    # 按记录的顺序输出
    for (i=1; i<=order_count; i++) {
        print order[i], data[order[i]]
    }
}

运行脚本的命令

把所有要合并的CSV文件放在当前目录,然后执行:

awk -f merge_csv.awk *.csv > merged_output.csv

执行后,merged_output.csv就是你想要的合并结果。

测试验证

用你给出的示例文件测试:

File1.csv内容:
1 ; 1.1 ; xyz
1 ; 1.2 ; abc
2 ; 2.1 ; gfa

File2.csv内容:
1 ; 1.1 ; dft
1 ; 1.2 ; asd
2 ; 2.1 ; qwe

运行脚本后,输出文件内容完全符合你的期望:

1 ; 1.1 ; xyz ; dft
1 ; 1.2 ; abc ; asd
2 ; 2.1 ; gfa ; qwe

内容的提问来源于stack exchange,提问作者Teo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:21:09