【问题标题】:How to replace only last match in a line with sed?如何用sed替换一行中的最后一个匹配项?
【发布时间】:2018-04-08 18:56:24
【问题描述】:

使用sed,我可以使用替换一行中的第一个匹配项

sed 's/pattern/replacement/'

所有匹配使用

sed 's/pattern/replacement/g'

如何只替换 last 匹配,而不管它之前有多少匹配?

【问题讨论】:

    标签: sed replace text-processing


    【解决方案1】:

    从我在其他地方发布的内容复制粘贴:

    $ # replacing last occurrence
    $ # can also use sed -E 's/:([^:]*)$/-\1/'
    $ echo 'foo:123:bar:baz' | sed -E 's/(.*):/\1-/'
    foo:123:bar-baz
    $ echo '456:foo:123:bar:789:baz' | sed -E 's/(.*):/\1-/'
    456:foo:123:bar:789-baz
    $ echo 'foo and bar and baz land good' | sed -E 's/(.*)and/\1XYZ/'
    foo and bar and baz lXYZ good
    $ # use word boundaries as necessary - GNU sed
    $ echo 'foo and bar and baz land good' | sed -E 's/(.*)\band\b/\1XYZ/'
    foo and bar XYZ baz land good
    
    $ # replacing last but one
    $ echo 'foo:123:bar:baz' | sed -E 's/(.*):(.*:)/\1-\2/'
    foo:123-bar:baz
    $ echo '456:foo:123:bar:789:baz' | sed -E 's/(.*):(.*:)/\1-\2/'
    456:foo:123:bar-789:baz
    
    $ # replacing last but two
    $ echo '456:foo:123:bar:789:baz' | sed -E 's/(.*):((.*:){2})/\1-\2/'
    456:foo:123-bar:789:baz
    $ # replacing last but three
    $ echo '456:foo:123:bar:789:baz' | sed -E 's/(.*):((.*:){3})/\1-\2/'
    456:foo-123:bar:789:baz
    

    进一步阅读:

    【讨论】:

      【解决方案2】:

      这可能对你有用(GNU sed):

      sed 's/\(.*\)pattern/\1replacement/' file
      

      使用贪婪吞噬模式空间,然后正则表达式引擎将退后一步并找到第一个匹配项,即最后一个匹配项。

      【讨论】:

      • 这里没有特定于 GNU 的内容;这应该适用于任何sed
      【解决方案3】:

      一种有趣的方法是使用rev 反转每行的字符并将您的 sed 替换向后写。

      rev input_file | sed 's/nrettap/tnemecalper/' | rev
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-03-22
        • 1970-01-01
        • 2018-12-18
        • 2012-09-19
        • 2016-11-23
        • 2019-11-21
        • 2017-12-19
        • 2010-09-13
        相关资源
        最近更新 更多