Linux下awk合并两文本文件脚本失效,result.txt为空求调试帮助
解决awk脚本匹配合并文件的问题
我看了你的脚本和需求,问题主要出在哈希字段的定位错误以及映射逻辑混乱上,导致脚本无法正确匹配两个文件中的哈希值,最终result.txt为空。下面一步步分析并给出修正方案:
原脚本的核心问题
- 哈希字段定位错误:在1.txt中,哈希值是每行的最后一个非空字段(比如第一行的
0f8caa3ced5dc172901a427410d20540是第13个字段),但你原脚本用$9(这是IP地址字段)作为哈希键,完全无法匹配2.txt中的哈希值。 - 映射逻辑混乱:原脚本中
a、b数组的定义没有明确对应2.txt的键值关系,反而拼接了1.txt的字段,逻辑完全颠倒了。 - 字段分割处理不当:处理2.txt时的FS/OFS设置没有考虑到哈希后可能有多个冒号或空格的情况(比如2.txt第三行的
:: demo)。
修正后的awk脚本
这个脚本会先读取2.txt构建哈希到对应值的映射,再遍历1.txt替换匹配的哈希,同时分离匹配行和不匹配行:
# 第一步:读取2.txt,构建哈希->对应值的映射表 FNR == NR { # 清理哈希值的首尾空格(避免空格导致匹配失败) hash = $1 gsub(/^[[:space:]]+|[[:space:]]+$/, "", hash) # 提取哈希后的值,去掉开头的空格和多余冒号 val = substr($0, index($0, ":") + 1) gsub(/^[[:space:]:]+/, "", val) map[hash] = val next } # 第二步:处理1.txt,替换匹配的哈希并分离结果 { # 找到当前行的哈希值(取最后一个非空字段) current_hash = "" for (i = NF; i >= 1; i--) { if ($i != "") { current_hash = $i break } } # 判断哈希是否在映射表中 if (current_hash in map) { # 替换最后一个非空字段为对应的值 for (i = NF; i >= 1; i--) { if ($i != "") { $i = map[current_hash] break } } # 写入匹配结果文件 print $0 > "result.txt" } else { # 写入不匹配结果文件 print $0 > "left.txt" } }
使用方法
将上述代码保存为merge_files.awk,然后执行以下命令:
awk -F'|' -f merge_files.awk 2.txt 1.txt
或者直接使用一行命令版本:
awk -F'|' 'FNR==NR{hash=$1;gsub(/^[[:space:]]+|[[:space:]]+$/,"",hash);val=substr($0,index($0,":")+1);gsub(/^[[:space:]:]+/,"",val);map[hash]=val;next}{current_hash="";for(i=NF;i>=1;i--){if($i!=""){current_hash=$i;break}}if(current_hash in map){for(i=NF;i>=1;i--){if($i!=""){$i=map[current_hash];break}}print $0>"result.txt"}else{print $0>"left.txt"}}' 2.txt 1.txt
结果验证
运行后会生成两个文件:
result.txt:包含1.txt中哈希匹配的行,且哈希已替换为2.txt的对应值left.txt:包含1.txt中哈希未匹配的行
这个脚本会处理所有边缘情况,比如2.txt中哈希后的多冒号、空格,以及1.txt中哈希位置不固定的情况。
内容的提问来源于stack exchange,提问作者Bhawan
相关产品推荐
相关产品推荐

