【问题标题】:sed whole word search and replacesed 全词搜索和替换
【发布时间】:2010-11-05 03:28:45
【问题描述】:

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

在做

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

还将替换我不希望这样做的 [oldtext] 的部分匹配项。

【问题讨论】:

    标签: shell sed


    【解决方案1】:
    正则表达式中的

    \b 匹配单词边界(即第一个单词字符和非单词字符之间的位置):

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

    【讨论】:

    • not posix | GNU sed好的
    • @OlegMazko 我也来寻找在 vim 中使用的 posix 可接受的方法,对我有用的是 s/\stackoverflow.com/questions/3864467/…(由于某种原因,无法像你一样嵌入它)。
    • 谢谢你,我快疯了,想把“和”这个词替换掉,所以\band\b 节省了一天:)
    • 将使用[[:space:]]word[[:space:]] 被认为可以接受@jimh
    • 对我不起作用。也许是不同的 sed 版本?在 CentOS 7 上是默认设置
    【解决方案2】:

    在 Mac OS X 上, 这些正则表达式语法都不能在 sed 中用于匹配整个单词

    • \bmyWord\b
    • \&lt;myWord\&gt;

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

    • /[[:&lt;:]]myWord[[:&gt;:]]/

    因此,例如,将 mint 替换为 minty 仅用于整个单词:

    • sed "s/[[:&lt;:]]mint[[:&gt;:]]/minty/g"

    来源:re_format man page

    【讨论】:

    • 只需通过 MacPorts 或 Homebrew 安装 GNU sed(以及所有其他 GNU 工具),并确保它首先出现在您的 PATH 中。让 Mac 相当可用是可能的。
    • @JimStewart 打破一堆假设“在 OS X 上时,像 OS Xers 一样”的工具的好方法。也就是说,我绝对可以建议 brew install coreutils,它是所有 gnu 的前缀工具。
    • brew install gnu-sed 使用gsed
    • 回答了我自己的问题。有一个包列表@apple.stackexchange.com/questions/69223/…
    • 使用 perl 总是更好的解决方案:perl -pe 's|\bone\b|two|g'。在 sed 到处失败时稳定工作。
    【解决方案3】:

    使用\b 作为单词边界:

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

    【讨论】:

    • 小心[]o,l --> [newtext],[newtext]。你显然是指sed -i 's/\boldtext\b/newtext/g'
    【解决方案4】:

    在我的一台机器上,用“\b”(不带引号)分隔单词不起作用。解决方案是使用“\&lt;”作为起始分隔符,使用“\&gt;”作为结束分隔符。

    Joakim Lundberg的例子来解释:

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

    【讨论】:

      【解决方案5】:

      对于符合 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
      

      【讨论】:

        猜你喜欢
        • 2014-09-13
        • 1970-01-01
        • 2016-04-27
        • 2021-02-18
        • 1970-01-01
        • 1970-01-01
        • 2014-03-14
        • 2015-01-04
        相关资源
        最近更新 更多