代码之家  ›  专栏  ›  技术社区  ›  Timur Shtatland

如何在“sed”(例如,no PREFIXPREFIX)中只向路径预加一次前缀(以幂等方式)?

  •  1
  • Timur Shtatland  · 技术社区  · 2 年前

    我有一个包含复杂多行命令和一些无关文本的文件。我需要预先设置某些路径(例如, /foo )带前缀 /bar 。脚本可以运行多次,但不能在多个前加前缀 /酒吧 /bar/foo ,再次运行,然后 收到 /酒吧/美食 /bar/bar/foo . 我必须使用 sed 与现有代码库保持一致。

    我得出了预期的结果(如下),但我的方法似乎很麻烦。有没有更好(更短、更少重复)的方法?

    $ echo '/foo' > infile
    $ cat infile 
    "/foo" /foo
    
    # Replace once, change expected:
    $ sed -i '\#bar/foo#!s#\(/foo\)#/bar\1#g' infile
    $ cat infile 
    "/bar/foo" /bar/foo
    
    # Replace twice - no change expected:
    $ sed -i '\#bar/foo#!s#\(/foo\)#/bar\1#g' infile
    $ cat infile 
    "/bar/foo" /bar/foo
    

    编辑:不要使用我的“解决方案”:它在一个重要的边缘情况下是错误的,请参阅下面的评论

    1 回复  |  直到 2 年前
        1
  •  1
  •   anubhava    2 年前

    你可以用这个 sed 带有可选组的解决方案以替换 /foo 具有 /bar/foo 但是,当需要时,请跳过匹配 /bar 已存在:

    sed -E 's~(/bar)?(/foo)~/bar\2~g' file
    

    RegEx Demo

    细节:

    • (/bar)? :匹配 可选择的 /酒吧 捕获组#1
    • (/foo) :匹配 /福 捕获组#2
    • /bar\2 /酒吧 其次是我们在捕获组#2中捕获的价值