Edit xml file using shell script / command

76,372

Solution 1

If you just want to replace <author type=''><\/author> with <author type='Local'><\/author>, you can use that sed command:

sed "/<fiction type='a'>/,/<\/fiction>/ s/<author type=''><\/author>/<author type='Local'><\/author>/g;" file

But, when dealing with xml, I recommend an xml parser/editor like xmlstarlet:

$ xmlstarlet ed -u /book/*/author[@type]/@type -v "Local"  file
<?xml version="1.0"?>
<book>
  <fiction>
    <author type="Local"/>
  </fiction>
  <Romance>
    <author type="Local"/>
  </Romance>
</book>

Use the -L flag to edit the file inline, instead to printing the changes.

Solution 2

xmlstarlet edit --update "/book/fiction[@type='b']/author/@type" --value "Local" book.xml

Solution 3

We could use a xsl-document doThis.xsl and process the source.xml with xsltproc into a newFile.xml.

The xsl is based on the answer to this question.

Put this into a doThis.xsl file

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" omit-xml-declaration="no"/> 

<!-- Copy the entire document    -->

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<!-- Copy a specific element     -->

<xsl:template match="/book/fiction[@type='b']/author">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>

<!--    Do something with selected element  -->
            <xsl:attribute name="type">Local</xsl:attribute>

        </xsl:copy>
</xsl:template>

</xsl:stylesheet> 

Now we produce the newFile.xml

$:   xsltproc -o ./newFile.xml ./doThis.xsl ./source.xml 

This will be the newFile.xml

<?xml version="1.0" encoding="UTF-8"?>
<book>
   <fiction type="a">
      <author type=""/>
   </fiction>
   <fiction type="b">
      <author type="Local"/>
   </fiction>
   <Romance>
       <author type=""/>
   </Romance>
</book>

The expression used to find type b fiction is XPath.

Solution 4

It is quite easy with sed. The following script will change the contents of file a.xml and will put the original to a.bak as a backup.

What it does is it searches each file for the string <author type=''> and replaces it with <author type='Local'>. The /g modifier means that it will try to make more than 1 replacement on each line if possible (not needed for your example file).

sed -i.bak "s/<author type=''>/<author type='Local'>/g" a.xml
Share:
76,372

Related videos on Youtube

VRVigneshwara
Author by

VRVigneshwara

Updated on September 18, 2022

Comments

  • VRVigneshwara
    VRVigneshwara over 1 year

    I need to do this using unix script or command There is a xml file in /home/user/app/xmlfiles like

    <book>
       <fiction type='a'>
          <author type=''></author>
       </fiction>
       <fiction type='b'>
          <author type=''></author>
       </fiction>
       <Romance>
           <author type=''></author>
       </Romance>
    </book>
    

    I want to edit author type in fiction as local .

       <fiction>
          <author type='Local'></author>
       </fiction>
    

    I need to change the author type which is in fiction tag with attribute b alone. Please help me with this using unix shell script or command. Thanks !

    • Darius
      Darius almost 9 years
      Why not use some text editor like vi / vim / emacs / gedit (pick any of your choice)? Or you can only use shell scripts and can't use any programs?
    • VRVigneshwara
      VRVigneshwara almost 9 years
      unfortunately i can use scritping only
    • Frank Thomas
      Frank Thomas almost 9 years
      I guess I'd recommend using xlst to transform the input into appropriate output, since that is the XMLish approach. you can perform XLST transformations in bash using xlstproc . linux.byexamples.com/archives/463/xslt-processor-command-lin‌​e
    • Marco M. von Hagen
      Marco M. von Hagen almost 9 years
      @FrankThomas Take a look at my XMLish answer and please tell what you think about it.
    • Thorbjørn Ravn Andersen
      Thorbjørn Ravn Andersen about 7 years
      @Darius you still need the editor to understand XML.
  • VRVigneshwara
    VRVigneshwara almost 9 years
    I need to change the author type which is in fiction tag alone.Is that possible to check. I think above code will change all author tags.
  • Marki555
    Marki555 almost 9 years
    Then you should have specified that in your question :) I see you edited the Q already... and also got better answer.
  • davidbaumann
    davidbaumann over 5 years
    A litte more explanatation and a link to the documentation would make your answer more helpful.
  • slhck
    slhck over 5 years
    That does not really provide more info. It would be more helpful if you edited your post, used full sentences, and explained your one line of code.
  • Kit
    Kit over 5 years
    man xmlstarlet
  • wilbur4321
    wilbur4321 about 5 years
    This answer is about as perfect as an answer can be, IMO!
  • Richard
    Richard over 3 years
    I can't up-vote your answer more than one time, so this comment will have to suffice to express my gratitude: Thanks a million! Now I can update my CodeArtifact password in my maven settings.xml using a cronjob.
  • Harry Cutts
    Harry Cutts about 3 years
    Note that if your XML document has a default namespace (i.e. an xmlns attribute on the top-level tag), you'll need to specify it to xmlstarlet as described here.