【发布时间】:2010-11-05 03:28:45
【问题描述】:
如何使用 sed 搜索和替换整个单词?
在做
sed -i 's/[oldtext]/[newtext]/g' <file>
还将替换我不希望这样做的 [oldtext] 的部分匹配项。
【问题讨论】:
如何使用 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 替换为 minty 仅用于整个单词:
sed "s/[[:<:]]mint[[:>:]]/minty/g"【讨论】:
sed(以及所有其他 GNU 工具),并确保它首先出现在您的 PATH 中。让 Mac 相当可用是可能的。
brew install coreutils,它是所有 gnu 的前缀工具。
brew install gnu-sed 使用gsed
perl -pe 's|\bone\b|two|g'。在 sed 到处失败时稳定工作。
使用\b 作为单词边界:
sed -i 's/\boldtext\b/newtext/g' <file>
【讨论】:
[]:o,l --> [newtext],[newtext]。你显然是指sed -i 's/\boldtext\b/newtext/g'
在我的一台机器上,用“\b”(不带引号)分隔单词不起作用。解决方案是使用“\<”作为起始分隔符,使用“\>”作为结束分隔符。
用Joakim Lundberg的例子来解释:
$ echo "bar embarassment" | sed "s/\<bar\>/no bar/g"
no bar embarassment
【讨论】:
对于符合 posix 的替代方案,考虑将单词边界匹配 (\b) 替换为扩展等效项 ([^a-zA-Z0-9]),同时考虑在行首 (^) 和行尾 (@987654324) 的出现@)。
但是,如果您想支持重复出现的要替换的单词(例如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
【讨论】: