17

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 !

5
  • 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?
    – Darius
    May 19 '15 at 13:11
  • unfortunately i can use scritping only May 19 '15 at 13:14
  • 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-line May 19 '15 at 13:47
  • @FrankThomas Take a look at my XMLish answer and please tell what you think about it. Jun 11 '15 at 13:04
  • @Darius you still need the editor to understand XML. Mar 8 '17 at 15:10
26

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.

2
11
xmlstarlet edit --update "/book/fiction[@type='b']/author/@type" --value "Local" book.xml
5
  • 4
    A litte more explanatation and a link to the documentation would make your answer more helpful. Nov 13 '18 at 14:09
  • 4
    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.
    – slhck
    Nov 13 '18 at 14:41
  • 1
    man xmlstarlet
    – Kit
    Nov 14 '18 at 18:27
  • This answer is about as perfect as an answer can be, IMO!
    – wilbur4321
    Apr 12 '19 at 4:30
  • 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.
    – Richard
    Jan 22 at 7:24
6

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.

2

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
2
  • 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. May 20 '15 at 6:00
  • Then you should have specified that in your question :) I see you edited the Q already... and also got better answer.
    – Marki555
    May 20 '15 at 10:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.