![sed 字边界不适用于冒号字符](https://linux22.com/image/199226/sed%20%E5%AD%97%E8%BE%B9%E7%95%8C%E4%B8%8D%E9%80%82%E7%94%A8%E4%BA%8E%E5%86%92%E5%8F%B7%E5%AD%97%E7%AC%A6.png)
我有以下文件
> 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"
全部替换字 aaa
bbb
在任何不包含冒号的行上使用:
$ 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”