全字搜索和替换

如何使用 sed 搜索和替换整个单词?

做什么

sed -i 's/[oldtext]/[newtext]/g' <file>

也将替换部分匹配的 [oldtext],我不希望它这样做。

130701 次浏览

B 在正则表达式中匹配单词边界(即第一个单词字符和非单词字符之间的位置) :

$ echo "bar embarassment" | sed "s/\bbar\b/no bar/g"
no bar embarassment

使用 \b作为单词边界:

sed -i 's/\boldtext\b/newtext/g' <file>

在我的一台机器上,用“ \b”(没有引号)分隔单词不起作用。解决方案是使用“ \<”来启动分隔符,使用“ \>”来结束分隔符。

Joakim Lundberg的例子来解释:

$ echo "bar embarassment" | sed "s/\<bar\>/no bar/g"
no bar embarassment

在 Mac OS X 上,这些正则表达式语法的 都不是Sed中工作,用于匹配整个单词

  • \bmyWord\b
  • \<myWord\>

现在听我说,以后相信我,这个丑陋的语法是你需要使用的:

  • /[[:<:]]myWord[[:>:]]/

因此,举个例子,用 薄荷味的代替 薄荷糖只是为了整个单词:

  • sed "s/[[:<:]]mint[[:>:]]/minty/g"

资料来源: Re _ format 手册页

对于符合 posx 的替代方案,可以考虑用扩展对等词([^a-zA-Z0-9])替换单词边界匹配(\b) ,同时考虑到行首(^)和行尾($)的出现。

但是,如果您想支持重复出现要替换的单词(例如 oldtext oldtext) ,这很快就变得不切实际。sed --posix不能识别诸如 \(^\|[^a-zA-Z0-9]\)之类的表达式,因此不能使用查找。

看来我们必须明确匹配所有可能的情况。这里有一个解决方案,以取代 mintminty:

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