用 awk 或 sed 替换 xml 文件的一部分

Pap*_*cel 2 regex xml bash awk sed

我想用另一个字符串替换下面<restApi></restApi>(包括restApi标签)之间的部分:

...
  <restApi>
    <baseUrl>https://domain.com/nexus</baseUrl>
    <forceBaseUrl>true</forceBaseUrl>
    <uiTimeout>60000</uiTimeout>
  </restApi>
...
Run Code Online (Sandbox Code Playgroud)

使用 awk,我使用以下命令进行替换:

awk '/<restApi>/,/<\/restApi>/ {sub(/.*/,"<sometag>stuff</sometag>")}1' file.xml
Run Code Online (Sandbox Code Playgroud)

问题是 awk 用替换字符串替换了每一行,所以我得到了这个输出:

...
<sometag>stuff</sometag>
<sometag>stuff</sometag>
<sometag>stuff</sometag>
<sometag>stuff</sometag>
<sometag>stuff</sometag>
...
Run Code Online (Sandbox Code Playgroud)
  • 我在 awk 命令中缺少什么"<sometag>stuff</sometag>"以在结果中只有一个?
  • 我该如何用 sed 来代替?
  • 更换过程中间距/标签丢失。我怎样才能保存它?

Tom*_*lak 5

正如我在上面的评论中指出的,使用 XML 感知工具。

XSLT 就是其中之一,所以这里有一个简单的样式表,它替换了<restApi>元素,同时保留了其他所有内容,包括空格和制表符。

<!-- newRestApi.xsl -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="node() | @*">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="restApi">
    <sometag>stuff</sometag>
  </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

使用 withxsltproc非常简单:

xsltproc newRestApi.xsl input.xml > output.html
Run Code Online (Sandbox Code Playgroud)