Linux下跨文件列匹配:在file2第4列搜索file1第4列并输出指定内容
解决方案:用Awk实现文件列匹配与内容合并
嘿,这个需求用Awk就能完美搞定,我给你整理了两种实现方式,逻辑清晰还容易调整,先看具体操作:
方法一:脚本文件形式(推荐,可读性高)
创建一个名为merge_files.awk的文件,内容如下:
BEGIN { # 第一步:读取file1.txt,建立第4列到1-3列的映射 while ((getline < "file1.txt") > 0) { map[$4] = $1 " " $2 " " $3 } close("file1.txt") # 第二步:读取file2.txt,收集匹配结果和所有原内容 while ((getline < "file2.txt") > 0) { # 保存file2的每一行到数组,后续输出原内容用 original_lines[++line_num] = $0 # 如果当前行第4列在file1的映射里,生成需要的组合行 if ($4 in map) { match_results[++match_num] = map[$4] " " $4 } } close("file2.txt") # 第三步:先输出所有匹配结果,再输出file2原有内容 for (i = 1; i <= match_num; i++) { print match_results[i] } for (i = 1; i <= line_num; i++) { print original_lines[i] } }
然后在终端运行:
awk -f merge_files.awk
方法二:单行命令形式(适合快速执行)
如果不想创建脚本文件,直接用这个单行命令:
awk 'BEGIN {while((getline<"file1.txt")>0) map[$4]=$1" "$2" "$3; close("file1.txt"); while((getline<"file2.txt")>0) {orig[++n]=$0; if($4 in map) matches[++m]=map[$4]" "$4}; close("file2.txt"); for(i=1;i<=m;i++) print matches[i]; for(i=1;i<=n;i++) print orig[i]}'
逻辑拆解
我给你理清楚脚本的工作流程,方便你理解和修改:
- 构建映射表:先读取
file1.txt的每一行,把第4列内容作为"键",对应的第1、2、3列拼接成字符串作为"值"存在map数组里,这样后续能快速通过第4列的值找到对应的1-3列内容。 - 收集内容:接着读取
file2.txt的每一行,一方面把所有行保存到数组(用来最后输出原内容),另一方面检查当前行第4列是否在map中,匹配的话就生成组合行存到结果数组。 - 输出内容:最后先打印所有匹配结果,再打印
file2.txt的原有内容,正好满足"匹配结果放在原有内容上方"的要求。
注意事项
- 如果你的文件列分隔符不是空格(比如制表符
\t),需要在awk命令里指定分隔符,比如:awk -F "\t" -f merge_files.awk - 如果
file1.txt里同一第4列对应多行内容,这个脚本只会保留最后一行的1-3列。如果需要处理重复键的场景,可以告诉我,我再调整脚本。
内容的提问来源于stack exchange,提问作者bapors
相关产品推荐
相关产品推荐

