按首列值匹配合并两个文件的技术实现需求
文本文件合并需求及解决方案建议
需求说明
需要实现两个文本文件的合并功能,规则如下:
- 当两个文件首列值相同时进行合并;若首列值不匹配,则在对应位置填充
NaN。 - 针对每个首列值,合并结果需取两个文件中该值对应行数的最大值,不足部分补
NaN;整体结果行数为两个文件总行数的最大值。 - 若其中一个文件为空,输出非空文件内容,对应空文件的列填充
NaN;首列值不匹配时,保留有数据文件的内容,另一文件对应列填充NaN。 - 最终结果需按首列数值排序。
示例文件
文件1内容
140 12.49 140 12.33 140 10.62 140 8.57 140 10.09 140 9.82 140 11.48 140 13.07 140 14.09 140 15.02 140 14.20 140 15.05 140 16.15 141 14.91 141 13.62 141 13.09 141 11.54 141 9.86 141 8.37 141 7.95 141 7.55 141 7.86 141 7.92 141 9.99 141 10.82 141 9.83 142 9.31 142 9.36 142 8.77 142 9.52 142 9.92 142 9.56 142 10.50 142 12.53 142 12.05 142 11.30 142 11.52 142 12.61 142 15.05
文件2内容
140 12.70 140 12.64 140 10.52 140 8.61 140 10.11 140 9.88 140 11.48 140 13.12 140 14.16 140 15.07 140 14.25 140 15.16 140 16.25 141 14.84 142 9.54 142 8.74 142 9.68 142 10.00 142 9.64 142 10.64 142 12.69 142 12.15 142 11.51 142 11.69 142 12.77 142 15.25
期望合并结果
140 12.49 140 12.70 140 12.33 140 12.64 140 10.62 140 10.52 140 8.57 140 8.61 140 10.09 140 10.11 140 9.82 140 9.88 140 11.48 140 11.48 140 13.07 140 13.12 140 14.09 140 14.16 140 15.02 140 15.07 140 14.20 140 14.25 140 15.05 140 15.16 140 16.15 140 16.25 141 14.91 141 14.84 141 13.62 141 NaN 141 13.09 141 NaN 141 11.54 141 NaN 141 9.86 141 NaN 141 8.37 141 NaN 141 7.95 141 NaN 141 7.55 141 NaN 141 7.86 141 NaN 141 7.92 141 NaN 141 9.99 141 NaN 141 10.82 141 NaN 141 9.83 141 NaN 142 9.31 142 9.54 142 9.36 142 8.74 142 8.77 142 9.68 142 9.52 142 10.00 142 9.92 142 9.64 142 9.56 142 10.64 142 10.50 142 12.69 142 12.53 142 12.15 142 12.05 142 11.51 142 11.30 142 11.69 142 11.52 142 12.77 142 12.61 142 15.25 142 15.05 142 NaN
补充示例(文件2行数更多时)
140 15.16 140 15.05 140 16.25 140 16.15 141 14.84 141 14.91 141 NaN 141 13.62 141 NaN 141 13.09 ... 142 15.25 142 12.61 142 NaN 142 15.05
现有脚本问题
现有AWK脚本仅能匹配单条首列值对应的数据,无法处理同一首列值多行的情况,也不满足行数补全、排序等需求:
awk 'NR==FNR{a[$1]=$2; next} {print $1, ($1 in a) ? a[$1] : "NaN", $1, $2}' file1.txt file2.txt
解决方案
以下是符合需求的AWK脚本实现:
#!/usr/bin/awk -f # 读取第一个文件,按首列分组存储每行数据并记录行数 NR == FNR { group1[$1][++count1[$1]] = $2 keys[$1] = 1 # 收集所有出现过的首列值 next } # 读取第二个文件,完成相同的分组存储 { group2[$1][++count2[$1]] = $2 keys[$1] = 1 } # 处理合并输出 END { # 按首列数值升序排序 PROCINFO["sorted_in"] = "@ind_num_asc" # 遍历每个首列值 for (key in keys) { # 获取当前首列值在两个文件中的最大行数 max_rows = (count1[key] > count2[key]) ? count1[key] : count2[key] # 逐行输出合并结果 for (i = 1; i <= max_rows; i++) { val1 = (i in group1[key]) ? group1[key][i] : "NaN" val2 = (i in group2[key]) ? group2[key][i] : "NaN" printf "%s %-8s %s %s\n", key, val1, key, val2 } } }
脚本说明
- 数据存储:用二维数组
group1、group2分别存储两个文件中每个首列值对应的所有第二列数据,count1、count2记录每个首列值的行数。 - 全量首列收集:
keys数组记录所有出现过的首列值,确保不会遗漏任何分组。 - 数值排序:通过
PROCINFO["sorted_in"] = "@ind_num_asc"实现首列值的数值升序排序。 - 行数补全:对每个首列值取两个文件中的最大行数,逐行输出,缺失位置填充
NaN。 - 格式对齐:使用
printf格式化输出,保证结果列对齐,和示例格式一致。
使用方法
将脚本保存为merge_files.awk,赋予执行权限后运行:
chmod +x merge_files.awk ./merge_files.awk file1.txt file2.txt
脚本会自动处理空文件场景:若其中一个文件为空,对应列全部填充NaN,保留另一个文件的所有数据。
内容的提问来源于stack exchange,提问作者Sorin Nistor
相关产品推荐
相关产品推荐

