对于包含以下记录的文件:
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