awk使用多个AND运算符进行特定模式匹配的代码问题排查
问题原因
你的代码存在两个核心逻辑错误,导致运行结果不符合预期:
- 冗余恒真条件:
($2 ~ /FOP/ || $2 !~ /FOP/)是永远成立的无效判断——任何字段要么匹配指定正则、要么不匹配,写不写这个条件对结果没有任何影响。 - 筛选逻辑完全写反:根据德摩根定律,你要排除同时满足4个条件的行($2匹配FOP、$4匹配ABC、$5以YX开头、$6匹配Clone),等价于保留「至少有1个排除条件不满足」的行。但你写的判断是
$4 !~/ABC/ && $5 !~ /^YX/ && $6 !~ /Clone/,要求三个字段同时不满足对应特征才打印,相当于仅保留$4不含ABC、$5不以YX开头、$6不含Clone的行,和你要的逻辑完全相悖,自然得不到预期结果。
修正方案
基础筛选代码
直接打印所有不满足“四个排除条件同时命中”的行即可,正则^YX已经可以匹配所有以YX开头的字段,不需要额外加.*:
awk -F '|' 'BEGIN{OFS=FS} !($2 ~ /FOP/ && $4 ~ /ABC/ && $5 ~ /^YX/ && $6 ~ /Clone/)' file
带重定向版本
如果需要把命中排除规则的记录单独重定向到其他文件(比如命名为exclude.log),可以用下面的写法:
awk -F '|' 'BEGIN{OFS=FS} { if ($2 ~ /FOP/ && $4 ~ /ABC/ && $5 ~ /^YX/ && $6 ~ /Clone/) { print > "exclude.log" } else { print } }' file
结果验证
用你提供的测试文件运行基础筛选代码:
- 第一行
|FOP|12345|ABC|YX0937|Clone|四个排除条件全中,被过滤(写入exclude.log) - 第二行
AED|FOP|12345|ABC|aacc|Clone|$5不以YX开头,不满足全中条件,保留 - 第三行
AUS|FOP|3446|XXW|tred|Clone|$4不匹配ABC,保留 - 第四行
|POP|3452|ABC|aacc|Clone|$2不匹配FOP,保留 - 第五行
|TOP|1234|KBJ|YX|Client|$2不匹配FOP、$4不匹配ABC、$6不匹配Clone,保留
注:你给出的预期输出未包含第五行,若第五行确实需要额外过滤,可以在判断条件中补充对应规则即可。
内容的提问来源于stack exchange,提问作者Nadia Alice
相关产品推荐
相关产品推荐

