【问题标题】:sed whole word search and replace but include other characterssed 整个单词搜索和替换但包含其他字符
【发布时间】:2014-04-18 09:31:58
【问题描述】:

要用sed 替换整个单词,可以这样做:

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

这取自another stackoverflow question。后续问题,如何更改单词的定义?

来自linuxtopia

GNU sed、ssed、sed16、sed15 和 sedmod 使用某些符号来定义“单词字符”和非单词字符之间的边界。一个单词字符适合正则表达式“[A-Za-z0-9_]”。

如何包括例如“——”?或者在我的特殊情况下,我想重命名 R 代码库中的变量,在那里它们到处都是“。” (在变量名中经常使用它代替“_”,例如google's R styleguide),所以我想包括“。”在一个词的定义中。

编辑:

说得更清楚,说我想把current.my.date <- my.date + today改成current.my.date <- any.date + datesed命令是什么?

例如修复这个命令

echo "current.my.date <- my.date + today" | sed "s/\bmy.date\b/any.date/g"
current.any.date <- any.date + today

因为它现在的形式也会改变current.my.date

【问题讨论】:

    标签: shell sed


    【解决方案1】:

    试试这个:

    $ echo "current.my.date <- my.date + today" |
        sed -r 's/(^|[^[:alnum:]_.])my\.date([^[:alnum:]_.]|$)/\1any.date\2/g'
    current.my.date <- any.date + today
    

    它假定“单词”是“字母数字或 _ 或 ”的序列。由该集合之外的字符分隔的字符,或以字符串开头 (^) 开头或以字符串结尾 ($) 开头。

    如果这不是您想要的,请发布更多示例输入和预期输出。

    听起来你需要一些变体:

    awk '{
        head = ""
        tail = $0
        while( match( tail, /(^|[^[:alnum:]_.])my\.date([^[:alnum:]_.]|$)/ ) ) {
            head = head substr(tail,1,RSTART-1) "any.date"
            tail = substr(tail,RSTART+RLENGTH-1)
        }
        print head tail
    }' file
    

    得到你想要的。

    【讨论】:

    • +1 用于使用纯 POSIX 正则表达式,希望这适合 OP。
    • 已经使用了一段时间,并且运行良好,但担心仍然存在它不起作用的情况。目前它在Var=Var 上失败,例如当要重命名的 2 个实例之间只有 1 个字母时。遗憾的是,没有办法实际复制 \b 行为并在其中修改它。
    • 是的,没错,分隔符只会在其中一个匹配项中“看到”。您需要切换到 awk - 我发布了一个 sn-p 作为您的起点,这并不完全是您所需要的,但希望您能理解并修改它以适应它。
    【解决方案2】:

    所以我想包括“。”在一个词的定义中

    你可以使用这个字符类:

    [A-Za-z0-9_.]
    

    如果您还想添加连字符,请使用:

    [A-Za-z0-9_.-]
    

    还请记住,添加这些内容后,您不能将\b 作为单词边界进行回复,因为连字符和点也被视为单词边界。对于这种情况,您可以使用否定字符类:

    [^A-Za-z0-9_.-]
    

    编辑:

    echo "foo-bar embarassment" | sed "s/\([A-Za-z0-9_.-]\+\)/no \1/g"
    no foo-bar no embarassment
    

    【讨论】:

    • 对不起,您需要什么命令?您刚刚问过如何在问题中包含点和连字符。提供一些示例输入,我也会协助 sed 命令。
    • 这个命令echo "bar embarassment" | sed "s/\bbar\b/no bar/g"变成了什么?如何仅替换可以包含点的整个单词?
    • 抱歉,这对我不起作用。我编辑了我的问题以包含一个示例。
    • @Cookie - 您不需要显示所有可能的输入,但显然只显示 1 不适合您。例如,发布 10 个您认为难以处理的示例以及相关的预期输出如何? Anubhava - +1 坚持下去 :-)!
    • 感谢@EdMorton。这就是我试图向 OP 解释的内容。在大多数情况下,如果 OP 想要添加点、连字符、括号等作为单词的一部分,(^| )( |$) 就足够了。
    猜你喜欢
    • 1970-01-01
    • 2012-05-05
    • 2010-11-05
    • 2014-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-11
    相关资源
    最近更新 更多