如果文本与正则表达式匹配,则 awk 进行替换。如果没有就用别的东西代替。这可以用 awk 实现吗?

如果文本与正则表达式匹配,则 awk 进行替换。如果没有就用别的东西代替。这可以用 awk 实现吗?

对于包含以下记录的文件:

ABC|YE0000123543|BLAH|XYZ|24.12.2025|J
ABC|YE0000123544|BLAH|MNO|24.12.2025|K

如果第四个字段包含 XYZ,则将其替换为 Y。如果不是,则将其替换为 N。

听起来很简单,对吧?显然好吧不是用 awk 匹配一些东西是非常困难的,如果不是不可能的话,或者我只是不明白。

替补比赛

$ echo "ABC|YE0000123543|BLAH|XYZ|24.12.2025|J"|awk -F '|' 'BEGIN { OFS=FS } {gsub(/XYZ/, "Y", $4);} {print $0}'
ABC|YE0000123543|BLAH|Y|24.12.2025|J

到目前为止,一切都很好!现在打印 N 来表示不匹配:

只是否定正则表达式,对吗?!/XYZ/

$ echo "ABC|YE0000123543|BLAH|MNO|24.12.2025|J"|awk -F '|' 'BEGIN { OFS=FS } {gsub(!/XYZ/, "N", $4);} {print $0}'
ABC|YE0000123543|BLAH|MNO|24.12.2025|J

不?它就是行不通。

看着其他答案SO 让我一无所知。似乎没有什么能够可靠地替代 awk 中不匹配的正则表达式。

任何指示将不胜感激。

答案1

正如@Romeo 还建议的那样,字符串相等性可以比正则表达式更准确。

我会写

awk 'BEGIN {FS=OFS="|"} {$4 = ($4 == "XYZ" ? "Y" : "N")} 1' file

答案2

你可以像这样更改脚本:

$ awk -F '|' 'BEGIN { OFS=FS } {if("XYZ"==$4) $4="Y" ;else $4="N"; print }' input_file >output_file

答案3

给猫剥皮有无数种方法...您似乎想替换整个字段 4,不是吗?尝试使用“条件”运算符:

awk -F '|' '{$4=($4=="XYZ")?"Y":"N"} 1' OFS="|" file5
ABC|YE0000123543|BLAH|Y|24.12.2025|J
ABC|YE0000123544|BLAH|N|24.12.2025|K

答案4

使用(以前称为 Perl_6)

~$ raku -ne 'my @a = .split("|"); @a.[3] eq "XYZ" ?? (@a.[3] = "Y") !! (@a.[3] = "N"); @a.join("|").put;'  file

或者

~$ raku -ne 'my @a = .split("|"); @a.[3] = (@a.[3] eq "XYZ" ?? "Y" !! "N"); @a.join("|").put;'  file

一定是这样吗awk?这是使用 Raku 的三元运算符的解决方案:“(条件)??True !!False”。上面的split/方法的好处join是,如果您想用逗号连接来创建一个简单的csv文件,它可以设置您。否则,Raku 的内容与awk发布的答案类似,指出 Raku(和 Perl5)是零索引的。

https://docs.raku.org/language/operators#index-entry-operator_ternary
https://raku.org

相关内容