使用AWK通过查找文件替换列值时遇空格匹配问题求助
解决AWK替换带空格键值对的问题
看起来你已经走了大半路啦,问题确实出在那些带空格的代码(比如Z XXX)上——默认的AWK字段分隔符是空格,所以你之前的脚本大概率把这类代码拆成了两个字段,只把Z作为键存在映射里,后面的不同值还会互相覆盖,自然没法正确匹配整个带空格的代码。
给你两种针对性的修改方案,按需选择:
方案1:通用文本替换(匹配任意位置的带空格代码)
如果你的原文件里代码可能出现在任意位置,用这个脚本读取查找文件时,把除最后一列外的所有字段合并成键,最后一列作为对应名称:
# 先处理查找文件,构建带空格的键值映射 NR==FNR { # 合并前NF-1个字段作为键(处理带空格的代码) key = $1 for (i=2; i<NF; i++) { key = key " " $i } map[key] = $NF # 最后一列是要替换成的名称 next } # 处理原文件,遍历映射替换所有匹配的键 { current_line = $0 for (code in map) { gsub(code, map[code], current_line) } print current_line }
运行命令示例:
awk -f replace.awk lookup.txt input.txt > output.txt
方案2:精确字段替换(代码在固定位置,比如冒号后)
如果原文件的格式很规整,比如每行是XXX: Z 123这种,代码固定在某个字段里,那用这个更精准,避免误替换其他地方的相同字符:
BEGIN { FS = ": " # 按冒号加空格分隔字段 OFS = ": " } # 同样先构建带空格的键值映射 NR==FNR { key = $1 for (i=2; i<NF; i++) { key = key " " $i } map[key] = $NF next } # 只替换冒号后的代码字段 { if ($2 in map) { $2 = map[$2] } print $0 }
为啥之前的脚本不行?
举个例子,假设查找文件里有一行Z 789 Cherry,默认AWK会把$1设为Z,$2设为789,$3设为Cherry,你的旧脚本可能把map[$1] = $2或者map[$1] = $3,这样映射里只有Z对应某个值,而不是完整的Z 789,自然没法匹配到原文件里的Z 789。
试试上面的方案,应该就能解决那些带空格代码的替换问题啦!
内容的提问来源于stack exchange,提问作者Fatjon Sakiqi
相关产品推荐
相关产品推荐

