Unix下实现两文件列匹配并输出指定结果的技术咨询
解决VT项匹配与按序输出对应值的问题
看起来你想用grep -Ff file1 file2来匹配两个文件里的VT项,但发现它没法满足你的需求——毕竟grep只能提取file2中包含file1里VT的行,没法按file1的顺序逐个处理每个VT项,也没法在无匹配时输出no_match。别担心,用awk就能完美解决这个问题,下面是具体的方案:
解决方案:使用AWK脚本处理
AWK可以轻松实现“先建立映射关系,再按目标顺序查询”的逻辑,具体脚本如下:
# 处理第一个文件(file_2),建立VT到对应首列的映射数组 NR == FNR { # 遍历当前行的所有字段,找到以VT开头的字段 for (i = 1; i <= NF; i++) { if ($i ~ /^VT/) { vt_map[$i] = $1 # 记录VT对应的首列内容 break # 每行仅一个VT项,找到后退出循环 } } next # 跳过后续逻辑,处理下一行 } # 处理第二个文件(file_1),按顺序输出结果 { printf "%s", $1 # 先输出首列的BlockID # 遍历从第二个字段开始的所有VT项 for (i = 2; i <= NF; i++) { current_vt = $i # 检查当前VT是否在映射数组中,输出对应值或no_match printf " %s", (current_vt in vt_map) ? vt_map[current_vt] : "no_match" } printf "\n" # 每行结束后换行 }
使用方法
- 将上述脚本保存为
match_vt.awk文件; - 在终端运行以下命令:
awk -f match_vt.awk file_2 file_1
或者直接使用单行命令(无需保存脚本):
awk 'NR==FNR{for(i=1;i<=NF;i++)if($i~/^VT/){vt_map[$i]=$1;break};next}{printf "%s",$1;for(i=2;i<=NF;i++)printf " %s",($i in vt_map)?vt_map[$i]:"no_match";print ""}' file_2 file_1
脚本工作原理
- 第一步(处理file_2):遍历file_2的每一行,找到以
VT开头的字段,将这个VT值作为键,当前行的第一个字段作为值,存入关联数组vt_map,建立VT与对应首列内容的映射关系。 - 第二步(处理file_1):按file_1的顺序,先输出首列的
BlockID,然后逐个检查每个VT项:如果VT存在于vt_map中,就输出对应的首列内容;否则输出no_match,最终得到你想要的有序结果。
用你的示例数据测试,输出结果正好是你预期的:
BlockID VT11742 no_match VT11744 no_match VT11050 crc_32-C1 VT11870 no_match VT12147 no_match VT12149 no_match VT12176 no_match VT12180 no_match
内容的提问来源于stack exchange,提问作者user3324491
相关产品推荐
相关产品推荐

