如何使用 sed 搜索和替换整个单词?
正在做
sed -i 's/[oldtext]/[newtext]/g' <file>
还将替换[oldtext]
我不希望这样做的部分匹配项。
正则表达式中的 \b 匹配单词边界(即第一个单词字符和非单词字符之间的位置):
$ echo "bar embarassment" | sed "s/\bbar\b/no bar/g"
no bar embarassment
在 Mac OS X 上,这些正则表达式语法在sed中都不能用于匹配整个单词
\bmyWord\b
\<myWord\>
现在听我说,以后再相信我,这个丑陋的语法是你需要使用的:
/[[:<:]]myWord[[:>:]]/
因此,例如,仅在整个单词中用mint替换mint :
sed "s/[[:<:]]mint[[:>:]]/minty/g"
用于\b
单词边界:
sed -i 's/\boldtext\b/newtext/g' <file>
在我的一台机器上,用“ \b
”(不带引号)分隔单词不起作用。解决方案是使用“ \<
”作为起始分隔符,“ \>
”作为结束分隔符。
用Joakim Lundberg的例子来解释:
$ echo "bar embarassment" | sed "s/\<bar\>/no bar/g"
no bar embarassment
对于符合 posix 的替代方案,请考虑将单词边界匹配 ( \b
) 替换为扩展的等效项 ( [^a-zA-Z0-9]
),同时考虑在行首 ( ^
) 和行尾 ( $
) 的出现。
但是,如果您想支持重复出现的要替换的单词(例如oldtext oldtext
),这很快就会变得不切实际。sed --posix
不识别诸如 的表达式\(^\|[^a-zA-Z0-9]\)
,并且您不能使用环视。
看来我们必须明确匹配所有可能的情况。mint
这是替换为的解决方案minty
:
echo 'mint 0mint mint mint0 mint__mint mint__ mint_ -mint mint mint mint_ mint -mint- mint mint mintmint mint' \
| sed --posix '
s/^mint$/minty/g;
s/^mint\([^a-zA-Z0-9]\)/minty\1/g;
s/\([^a-zA-Z0-9]\)mint$/\1minty/g;
s/\([^a-zA-Z0-9]\)mint\([^a-zA-Z0-9]\)mint\([^a-zA-Z0-9]\)mint\([^a-zA-Z0-9]\)/\1minty\2minty\3minty\4/g;
s/\([^a-zA-Z0-9]\)mint\([^a-zA-Z0-9]\)mint\([^a-zA-Z0-9]\)/\1minty\2minty\3/g;
s/\([^a-zA-Z0-9]\)mint\([^a-zA-Z0-9]\)/\1minty\2/g;
'
# minty 0mint minty mint0 minty__minty minty__ minty_ -minty minty minty minty_ minty -minty- minty minty mintmint minty