Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace section of an xml file with awk or sed

Tags:

regex

bash

xml

sed

awk

I'd like to replace the section below between <restApi> and </restApi> (including restApi tags) with another string:

...
  <restApi>
    <baseUrl>https://domain.com/nexus</baseUrl>
    <forceBaseUrl>true</forceBaseUrl>
    <uiTimeout>60000</uiTimeout>
  </restApi>
...

Using awk, I use the following command to do the replacement :

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

The problem is that awk replaces each line with the replacement string so I'm getting this output:

...
<sometag>stuff</sometag>
<sometag>stuff</sometag>
<sometag>stuff</sometag>
<sometag>stuff</sometag>
<sometag>stuff</sometag>
...
  • What am I missing in the awk command to have only one "<sometag>stuff</sometag>" in the result?
  • How do I do it with sed instead?
  • Spacing/tabs get lost during replacement. How can I preserve it?
like image 795
PapelPincel Avatar asked Jan 21 '26 09:01

PapelPincel


1 Answers

As pointed out in my comment above, use an XML aware tool.

XSLT is one, so here is a simple stylesheet that replaces <restApi> elements while leaving everything else alone, including spaces and tabs.

<!-- 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>

Use with xsltproc is dead-simple:

xsltproc newRestApi.xsl input.xml > output.html
like image 154
Tomalak Avatar answered Jan 24 '26 05:01

Tomalak



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!