【问题标题】:Find replace string before and after查找前后替换字符串
【发布时间】:2017-10-09 14:11:45
【问题描述】:

我一直在尝试进行 sed 替换。出于某种原因,我无法理解 sed 和正则表达式(这是我的第二个 sed 问题)

基本上我想查找文本并替换,然后找到下一次出现的某些文本并替换它

到目前为止我有这个

echo "This could be anywhere and this bit should be changed \$\{hcvar-BookName\} and this would remain" | sed 's/$\\{hcvar-/" + hcvar-/g'

这会返回:

*This could be anywhere and this bit should be changed " + hcvar-BookName\} and this would remain*

但是我想返回

*This could be anywhere and this bit should be changed " + hcvar-BookName + " and this would remain*

这会将 } 替换为 + "

逻辑是这样的:

Find: \$\{hcvar-
Replace with:  " + hcvar-
Then find the next occurrence of: \}
Replace with: + "

要替换的第二位将紧跟在包含以下内容的字符串之后:hcvar-

这应该适用于以下字符串示例

  • 这可能在任何地方,应该更改此位 \${hcvar-BookName} 这将保留
  • 这可能在任何地方,并且 应该更改此位 \${hcvar-somethingelse} 这将 留下
  • 这可能在任何地方,应该更改此位
    \${hcvar-wouldnevercontainspaces} 这将保留

任何帮助将不胜感激。

【问题讨论】:

    标签: sed


    【解决方案1】:

    假设您的输入实际上是:

    ... changed ${hcvar-BookName} and ...
    

    然后以下将起作用:

    $ sed 's/${\([^}]*\)}/" + \1 + "/' file.txt
    This could be anywhere and this bit should be changed " + hcvar-BookName + " and this would remain
    

    注意使用单引号来保留shell的特殊字符:

    $ echo '...changed ${hcvar-BookName} and ...' | sed '...' 
    

    如果输入确实使用\{,即:... $\{hello\} ...,那么这可能有效:

    $ sed 's/$\\{\([^}]*\)\\}/" + \1 + "/' file.txt
    This could be anywhere and this bit should be changed " + hcvar-BookName + " and this would remain
    

    细分:

    s/            /          / # Replace ... with ...
      ${         }             # Literal ${ and literal }
        \(     \)              # \( and \) is a capturing group
          [^}]*                # Match everything but } zero or more times
                   " + \1 + "  # \1 will be expanded to the captured result
                               # from \(, \). The rest is literal
    

    如果您需要在每行上进行多次替换,请添加 global:

    s/pattern/replacement/g
    #                     ^ Global flag
    

    【讨论】:

      【解决方案2】:

      你需要用反斜杠转义 $:

      echo "This could be anywhere and this bit should be changed \$\{hcvar-BookName\} and this would remain" | sed -e 's/\$\\{hcvar-/" + hcvar-/g' -e 's/\\}/ +/'

      输出:

      This could be anywhere and this bit should be changed " + hcvar-BookName + and this would remain

      【讨论】:

      • 在 POSIX 中,如果它不是替换命令的 pattern 部分中的最后一个字符,则 sed $ 是文字。然而,在许多风格中,如果$ 是最后一个逻辑字符,则s/\(a\|$\)/b/ 将不是文字,即:s/\(a\|$\)/b/ 将用b 替换模式空间之后的a 或空字节。
      最近更新 更多