sed 字边界不适用于冒号字符

sed 字边界不适用于冒号字符

我有以下文件

> cat tmp
"aaa"
"aaa:xyz"

期望的输出是

"bbb"
"aaa:xyz"

我正在使用以下 sed 命令

sed "s/\baaa\b/bbb/" tmp

但通过这个命令,我得到

"bbb"
"bbb:xyz"

冒号字符似乎被视为单词边界。如何在仅更改第一行而不更改第二行的情况下获得所需的输出?我什至尝试了以下但没有效果

sed "s/\Baaa\B/bbb/" tmp
sed "s/\baaa\B/bbb/" tmp
sed "s/\Baaa\b/bbb/" tmp

编辑:我必须在同一个文件上使用其他 sed 命令,如下所示

's/aaa:xyz/ttt/' tmp

所以,只有在没有冒号的情况下我才能进行替换。无论行中是否存在冒号,我都应该能够进行替换

答案1

GNU\b零宽度字边界模式在字字符和非字字符之间进行匹配。 “单词字符”通常是任何字母数字字符和下划线 ( _)。这意味着将在字符串和\b之间匹配。aaa:aaa:

下面通过将 的\b所有匹配替换为 来说明示例文档中的匹配位置:\b*

$ sed 's/\b/*/g' file
"*aaa*"
"*aaa*:*xyz*"

要将所有实例替换"aaa""bbb",请使用

$ sed 's/"aaa"/"bbb"/g' file
"bbb"
"aaa:xyz"

全部替换 aaabbb在任何不包含冒号的行上使用:

$ sed '/:/!s/\baaa\b/bbb/g' file
"bbb"
"aaa:xyz"

aaa要将后面不是冒号的所有单词替换为bbb

$ sed -e 's/\baaa\([^:]\)/bbb\1/g' -e 's/\baaa$/bbb/' file
"bbb"
"aaa:xyz"

注意这里的第一个替换需要表示aaa子串接下来是另一个角色。这意味着aaa该行最末端的子字符串不会被替换。这就是为什么我们对这种情况进行单独替换的原因。

答案2

如果不匹配,:请将 aaa 替换为 bbb:

sed '/:/! s/aaa/bbb/g' test.txt 

使用 Perl:

perl -pe 'if(!/:/){s/aaa/bbb/}' tmp

答案3

使用 sed:

sed 's/"aaa"/"bbb"/' file

输出:

“bb”
“aaa:xyz”

相关内容