求助:使用Linux下Awk实现跨文件匹配并更新字段
没问题,我来帮你用Awk快速搞定这个需求!
核心思路
先把文件2中第1列(Billdoc)存在且第2列(Curr)非INR的记录提取出来,存到一个关联数组里做标记;然后遍历文件1,只要第1列(documentN)在这个标记数组里,就把第2列替换成EXPWT,否则保留原内容。
实现代码
你可以直接用一行命令搞定,也可以写成脚本文件:
一行命令版本
awk 'NR==FNR{if($2!="INR")non_inr_docs[$1]=1;next} {if($1 in non_inr_docs)$2="EXPWT";print}' file2.txt file1.txt
脚本文件版本(更易读)
创建一个update_supply_type.awk文件,内容如下:
# 处理第一个输入文件(file2.txt):收集符合条件的Billdoc NR == FNR { # 如果当前行的Curr列不是INR,就把对应的Billdoc存入数组 if ($2 != "INR") { non_inr_docs[$1] = 1 } # 跳过后续逻辑,继续处理file2的下一行 next } # 处理第二个输入文件(file1.txt) { # 如果当前行的documentN在标记数组里,替换supply type为EXPWT if ($1 in non_inr_docs) { $2 = "EXPWT" } # 打印处理后的行 print }
然后运行脚本:
awk -f update_supply_type.awk file2.txt file1.txt
代码解释
NR == FNR:Awk的经典写法,用来判断当前正在处理的是第一个输入文件(这里是file2.txt)。NR是全局记录数,FNR是当前文件的记录数,处理第一个文件时两者相等。non_inr_docs[$1] = 1:把file2中符合条件的Billdoc作为数组的键,值设为1(仅用来标记存在)。next:跳过后续代码,直接处理file2的下一行,避免执行后面处理file1的逻辑。- 处理file1时,检查第1列是否在
non_inr_docs数组中,是则替换第2列,最后打印整行。
注意事项
- 分隔符问题:如果你的文件是用逗号、制表符或其他非空格分隔的,需要用
-F参数指定分隔符。比如CSV文件:awk -F',' 'NR==FNR{if($2!="INR")non_inr_docs[$1]=1;next} {if($1 in non_inr_docs)$2="EXPWT";print}' file2.csv file1.csv - 修改原文件:不要直接把输出重定向到原文件(比如
awk ... > file1.txt),会先清空原文件导致数据丢失。正确做法是先输出到临时文件,再替换:awk ... file2.txt file1.txt > temp.txt && mv temp.txt file1.txt - 重复记录:如果file2中同一个Billdoc有多行,只要其中一行的Curr非INR,就会标记该Billdoc需要替换,符合你的需求。
内容的提问来源于stack exchange,提问作者as7951
相关产品推荐
相关产品推荐

