如何修改AWK脚本以忽略文件中无匹配模式的行?
没问题,这其实是AWK最常用的基础功能之一,核心就是利用AWK的模式匹配机制来过滤行——只有匹配指定模式的行才会被处理,不匹配的直接跳过。我结合你给出的OSM(OpenStreetMap)文本示例,给你具体讲几种实现方式:
基础用法:直接保留匹配行
AWK的核心语法是 pattern { action },如果只写pattern不写action,默认的行为就是打印匹配的行。所以要忽略不匹配的行,只需要把你要匹配的模式写出来就行。
比如,如果你想保留所有包含<tag k="highway"的行(也就是带道路标签的条目),脚本可以写成:
/<tag k="highway"/
或者更明确地写出打印动作(效果完全一样):
/<tag k="highway"/ { print }
运行这个脚本处理你的OSM文本,就只会输出包含highway标签的行,其他不匹配的行都会被自动忽略。
结合已有脚本修改
如果你的AWK脚本已经有处理逻辑(比如提取字段、修改内容),只需要把匹配模式加到原有动作的前面,这样只有匹配的行才会执行后续动作。
比如原来的脚本是提取每行的第一个字段:
{ print $1 }
现在要只处理包含<node>的行,就改成:
/<node>/ { print $1 }
这样不包含<node>的行(比如<way>或者其他行)就会被跳过,不会执行print $1的动作。
匹配多个模式
如果需要保留满足任意一个模式的行,可以用正则表达式的|(或)操作符:
/<node>|<way>/
这个脚本会保留所有包含<node>或<way>的行,忽略其他行。
大小写不敏感匹配
如果你的文本里可能有大小写混合的情况(比如Highway而不是highway),可以在脚本开头加上IGNORECASE=1开启大小写不敏感模式:
BEGIN { IGNORECASE=1 } /<tag k="highway"/
举个实际的例子,用你的OSM文本片段测试:
<nd ref...
用/<tag k="highway"/这个脚本处理后,会输出:
<tag k="highway" v="turning_circle"/>
其他不包含这个模式的部分都会被忽略。
内容的提问来源于stack exchange,提问作者Gray

