有没有一种方法使用 sed 和 awk 搜索行(在文件中)的每个最后一个(按空格分隔)字段,匹配搜索值(即使字符串在最后一个字段之前的字段中匹配,也不会触及其他字段),并且该搜索值可以更改为其他值吗?
210983342900 342832423-1 i2301rw1900 309212dw90 900
9328423ABC 32091840-943543-9435 3012=32193900 301 3029432 334
210983342900ABCDE 342832423-1 i2301rw1900 309212dw90 900
9328423 32091840-943ABC3-9435 3012=32193900 301 3029432 ABC
3843209898 48435843098543098543 43985439859209438543 499 ABC
因此,在每个最后一个字段搜索 ABC,并将每个找到的值更改为 DEFG,或者在每个最后一个字段搜索 900 并将其更改为 000
你们能分解一下并解释一下解决方案吗?
答案1
echo 'This is terrible, I feel terrible' | awk '{if ($NF~"^terri") $NF="good"; print}'
这将做到这一点。
$NF
是位置 处的字段NF
。这里awk
是字段的数量,所以它是最后一个字段。
$NF~"^terri"
使用~
来匹配正则表达式。==
如果您想要精确匹配,则可以使用。
$NF="good"
将替换该字段,但前提是if
满足条件。
最后print
打印整个记录。
echo '
210983342900 342832423-1 i2301rw1900 309212dw90 900
9328423ABC 32091840-943543-9435 3012=32193900 301 3029432 334
210983342900ABCDE 342832423-1 i2301rw1900 309212dw90 900
9328423 32091840-943ABC3-9435 3012=32193900 301 3029432 ABC
3843209898 48435843098543098543 43985439859209438543 499 ABC
' | awk '{if ($NF=="ABC") $NF="DEFG"; print}'
答案2
和sed
:
sed -E 's/([[:blank:]]+)ABC$/\1whatever/' infile
-E
启用扩展正则表达式,所以我们不需要转义(
,)
或者+
在这里。[:blank:]
仅匹配空格或制表符[[:blank:]]
正则表达式中的字符类仅在字符列表的括号内有效。[[:blank:]]+
匹配一个或多个空格或制表符(...)
括号创建一个组匹配,并将\1
作为第一组的反向引用;\2
第二组、\3
第三组、直至\9
第九组;我们只定义了一场小组赛。ABC
完全匹配ABC
字符串。$
是线锚点的末端在替换部分,我们返回第一组比赛
\1
;这用于保留字符串之前的任何空格ABC
,并将被替换为whatever
字符串。
将最后一个字段替换为whatever
:
sed -E 's/([[:blank:]]+)[^[:blank:]]*$/\1whatever/' infile
你注意到^
括号里面了[^[:blank:]]
吗?如果它首先出现在字符类中,那么它就是否定字符,因此给定的字符类将匹配除空格或制表符之外的任何字符。请注意whatever
,如果行以尾随空格结尾,则字符串将附加到行尾,因为使用了称为零个或多个字符的*
量词。如果您不希望发生这种情况,[^[...]]*
请将其更改为。[^[:blank:]]+