【问题标题】:Replace string between two patterns with sed - no error, no result用 sed 替换两个模式之间的字符串 - 没有错误,没有结果
【发布时间】:2017-04-30 03:26:18
【问题描述】:

我要更改用户名的文件示例:

<host><![CDATA[localhost]]></host>
<username><![CDATA[root]]></username>

Here is my regex test 以确保匹配。

最后是 sed 命令,它没有错误地完成并且没有改变任何东西:

sed -i -e 's/(<username><!\[CDATA\[).*(\]\]><\/username>)/TEST/g' path/to/file.xml

这应该是结果:

<host><![CDATA[localhost]]></host>
TEST

除了根本不替换之外,我还需要它像这样工作,以便在前后保留捕获组,有效地只替换用户名:

sed -i -e 's/(<username><!\[CDATA\[).*(\]\]><\/username>)/\1TEST\2/g' path/to/file.xml

但这会返回此错误:

sed: -e expression #1, char 57: invalid reference \2 on `s' command's RHS

所以我认为捕获组以某种方式松散地匹配,因为它并没有真正捕获它们,这使得替换首先不会替换任何东西?

我想要的最终结果是这样的:

<host><![CDATA[localhost]]></host>
<username><![CDATA[TEST]]></username>

【问题讨论】:

  • 为什么要使用正则表达式来解析 XML?无论如何,您没有任何捕获组 - 您需要使用 \(..\) 或(在 GNU sed 中)添加 -r 选项以使用扩展正则表达式语法。
  • 不一定解析 XML,只是替换两个模式之间的文本。你评论中的建议是我让它工作的方式,所以谢谢你。我根本不知道扩展的正则表达式。这就是我的 SED 现在在我的循环中的样子:sed -i -r -e 's/(&lt;'"$key"'&gt;&lt;!\[CDATA\[).*(\]\]&gt;&lt;\/'"$key"'&gt;)/\1'"${db_local[$key]}"'\2/g' ${path_local[site]}/path/to/file.xml

标签: regex bash sed


【解决方案1】:

一种可能更精细的 awk 解决方案:

 awk '{if ($0 ~ /username/) gsub(/CDATA\[.+\]/, "CDATA[TEST]"); print $0 }' file.txt

言辞:

如果该行包含用户名,则将 CDATA[] 的所有实例替换为 CDATA[TEST]。这将改变线路。然后打印每一行。如果需要,可以进一步完善正则表达式。

【讨论】:

    【解决方案2】:
    awk '{sub(/root/,"TEST")}1' file
    
    <host><![CDATA[localhost]]></host>
    <username><![CDATA[TEST]]></username>
    

    【讨论】:

    • 最好也对您的答案提供一些解释
    【解决方案3】:

    您没有任何捕获组 - 您需要使用 (..) 或(在 GNU sed 中)添加 -r 选项以使用扩展正则表达式语法。 ——托比·斯佩特

    我根本不知道扩展的正则表达式。这就是我的 SED 现在在我的循环中的样子:
    sed -i -r -e 's/(&lt;'"$key"'&gt;&lt;![CDATA[).*(]]&gt;&lt;\/'"$key"'&gt;)/\1'"${db_local[$key]}"'\2/g' ${path_local[site]}/path/to/file.xml – a_rts

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-22
      • 2023-02-04
      • 2021-07-23
      • 2019-12-03
      • 1970-01-01
      • 2017-06-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多