如何用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 } }
脚本说明
- 数据存储:用
file1、file2、file3三个数组分别存储每个文件中name对应的完整行数据,同时用all_names数组记录所有出现过的name,确保不遗漏任何条目。 - NA占位处理:预先定义
na变量为NA,NA,NA,当某个name在对应文件中不存在时,直接用该占位符填充。 - 全量输出:在END块中遍历所有
name,依次拼接三个文件的对应数据(或NA)并输出,覆盖所有需求场景:三文件共有、至少两文件共有、单文件独有。
使用方式
直接执行脚本并传入三个文件:
awk -f merge_csv.awk file_1 file_2 file_3
内容的提问来源于stack exchange,提问作者vibhu sharma
相关产品推荐
相关产品推荐

