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

如何用awk比对三个文件的name列并合并输出全量数据

三CSV文件基于name列的全量合并脚本修正

需要将三个CSV文件基于name列进行比对合并,输出包含以下三类内容的结果文件:

  • 三个文件共有的name对应数据
  • 至少两个文件共有的name对应数据
  • 仅单个文件独有的name对应数据
    结果需保留每个文件的id、name、value列。现有awk脚本仅支持两文件比对,且无法正确输出独有值,需修正。

输入文件示例

$ cat file_1
id,name,value
1,a,20
2,b,34
3,c,5

$ cat file_2
id,name,value
1,a,27
2,b,55
7,d,15
9,z,100

$ cat file_3
id,name,value
1,a,77
2,b,95
11,d,83
6,y,109

预期输出

id,name,value,id2,name2,value2,id3,name3,value3
1,a,20,1,a,27,1,a,77
2,b,34,2,b,55,2,b,95
3,c,5,NA,NA,NA,NA,NA,NA
NA,NA,NA,7,d,15,11,d,83
NA,NA,NA,9,z,100,NA,NA,NA
NA,NA,NA,NA,NA,NA,6,y,109

现有问题脚本

#!/usr/bin/awk -f

BEGIN {
    FS = OFS = ",";
    print "id,name,value,id2,name2,value2,id3,name3,value3";
}


function print_na_row(name) {
    print name, "NA", "NA", "NA", "NA", "NA", "NA";
}

# Read file1.csv and store the data in an array
NR == FNR && FNR > 1 {
    id = $1;
    name = $2;
    value = $3;
    
    file1_data[name] = id "," value;
    next;
}

# Read file2.csv and file3.csv and merge with data from file1.csv
FNR > 1 {
    id = $1;
    name = $2;
    value = $3;
    
    current_row = id "," value;
    if (name in file1_data) {
        print name, file1_data[name], current_row;
        delete file1_data[name];  # Remove the matched entry to handle unique values in file1.csv
    } else {
        print_na_row(name);
    }
}
END {
    for (id in file1_data) {
        print_na_row(name);
    }
}

修正后的脚本

#!/usr/bin/awk -f

BEGIN {
    FS = OFS = ","
    # 输出表头
    print "id,name,value,id2,name2,value2,id3,name3,value3"
    # 定义NA占位符的默认值
    na = "NA,NA,NA"
}

# 读取第一个文件,存储每个name对应的id,name,value
FNR == NR && FNR > 1 {
    key = $2
    file1[key] = $1 "," $2 "," $3
    # 记录所有出现过的name
    all_names[key] = 1
    next
}

# 读取第二个文件
FNR > 1 && ARGIND == 2 {
    key = $2
    file2[key] = $1 "," $2 "," $3
    all_names[key] = 1
    next
}

# 读取第三个文件
FNR > 1 && ARGIND == 3 {
    key = $2
    file3[key] = $1 "," $2 "," $3
    all_names[key] = 1
}

END {
    # 遍历所有name,输出对应数据,无数据则补NA
    for (key in all_names) {
        f1 = (key in file1) ? file1[key] : na
        f2 = (key in file2) ? file2[key] : na
        f3 = (key in file3) ? file3[key] : na
        print f1, f2, f3
    }
}

脚本说明

  1. 数据存储:用file1、file2、file3三个数组分别存储每个文件中name对应的完整行数据,同时用all_names数组记录所有出现过的name,确保不遗漏任何条目。
  2. NA占位处理:预先定义na变量为NA,NA,NA,当某个name在对应文件中不存在时,直接用该占位符填充。
  3. 全量输出:在END块中遍历所有name,依次拼接三个文件的对应数据(或NA)并输出,覆盖所有需求场景:三文件共有、至少两文件共有、单文件独有。

使用方式

直接执行脚本并传入三个文件:

awk -f merge_csv.awk file_1 file_2 file_3

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 04:43:31