Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I am trying to add field at the end of tag using sed script. Suppose I have a tag in XML file:

<book name="Sed tutorial" price="250"/>

Now I want to add field as Book_Width="A" after end of <book/> tag so that my tag becomes:

<book name="Sed tutorial" price="250" Book_Width="A"/>

I tried with sed:

sed '/<book "[^>]*>/ a Book_Width="A"'

but it gives:

<book name="Sed tutorial" price="250"/>
Book_Width="A"
share|improve this question
    
Related :) –  Kroltan 10 hours ago

3 Answers 3

up vote 10 down vote accepted

You should not parse xml with sed, use an xml parser like xmlstarlet instead. For your task it would be:

xmlstarlet ed -O --inplace --insert "/book" --type attr -n Book_Width -v A xml_file

The file content is then:

<book name="Sed tutorial" price="250" Book_Width="A"/>
  • The ed means edit mode to edit the xml tree
  • -O omits the xml tag
  • We want to insert something with --insert
  • "/book" is the path where to insert
  • --type attr: it's an attribute, we want to insert
  • The name -n of the attribute
  • The value -v
share|improve this answer
    
can I update xml_file rather printing its output –  krishna 14 hours ago
    
@krishna Yes with --inplace I added it to my answer –  chaos 14 hours ago

in sed "a" appends a pattern IN A NEW LINE.

what you want to do is replace (substitute). Let's use a colon as separator for clarity:

sed 's:\(<book.*\)\(/>\):\1 Book_Width="A"\2:'

anything in \( .. \) is a pattern memorized by the order of appearance and recalled by \indexnumber , e.g. \1 will reproduce the first pattern saved.

So we are memorizing <book name="Sed tutorial" price="250" as pattern 1 and /> as pattern 2 and just insert Book_Width="A" in the middle.

echo '<book name="Sed tutorial" price="250"/>' | sed 's:\(<book.*\)\(/>\):\1 Book_Width="A"\2:'
<book name="Sed tutorial" price="250" Book_Width="A"/>
share|improve this answer

With awk you can do something like this:

Supposing the line is in file file1.xml then:

awk -F '/' '{print $1,"Book_Width=\"A\"",FS,$2}' file1.xml
share|improve this answer
    
This is not checking that the tag is "book" –  glenn jackman 11 hours ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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