如何使用grep/awk基于索引TSV文件补全另一文件缺失信息
TSV文件匹配填充操作方法
针对需要把索引文件(file2)的关联信息匹配填充到主文件(file1)的需求,优先推荐用awk实现,性能远高于grep方案,尤其适合主文件行数远大于索引文件的场景。
推荐方案:awk 实现(大文件友好)
直接在终端执行以下命令即可:
awk 'NR==FNR{map[$1]=$0; next} {print map[$1]}' file2.tsv file1.tsv > matched_result.tsv
命令逻辑说明
- 执行时awk会按顺序先读入
file2.tsv(索引文件),再读入file1.tsv(主文件) NR==FNR是awk内置判断逻辑:仅当处理第一个输入文件(即file2.tsv)时条件成立map[$1]=$0:把索引文件每行的第一列(item名)作为键,整行内容作为值,存入名为map的关联数组next:跳过后续逻辑,直接处理索引文件的下一行
- 处理第二个输入文件(file1.tsv)时,逐行拿当前行的item名作为键,从
map数组中取出之前存好的完整关联行打印 - 最终结果会重定向输出到
matched_result.tsv文件中,和预期输出完全一致
可选优化
如果file1中存在file2索引里找不到的item,上面的命令会输出空行,如果需要自动过滤无匹配的行,可以用修改后的命令:
awk 'NR==FNR{map[$1]=$0; next} $1 in map{print map[$1]}' file2.tsv file1.tsv > matched_result.tsv
备选方案:grep 实现(仅适合小文件)
grep方案需要逐行遍历主文件、反复搜索索引文件,大文件场景下性能极差,仅适合临时处理小体积文件:
while read item; do grep -P "^$item\t" file2.tsv; done < file1.tsv > grep_result.tsv
注意点
-P参数启用Perl正则支持,用^锚定行首、\t匹配制表符,避免把item_1和item_11这类前缀相似的item误匹配- 主文件超过10万行时不要用这个方法,运行速度会比awk方案慢几十到上百倍
通用注意事项
- 两个文件中的item名不能带多余的前后空格、制表符,否则会出现匹配失败的问题
- 输出文件默认保留原索引文件的制表符分隔格式,无需额外处理格式
内容的提问来源于stack exchange,提问作者WillDmz
相关产品推荐
相关产品推荐

