0

i have an xml file, file.xml

like below:

<?xml version="1.0" encoding="UTF-8"?>

<bookstore>

<book category="cooking">
  <title lang="en">Everyday Italian</title>
  <author>Giada De Laurentiis</author>
  <year>2005</year>
  <price>30.00</price>
</book>

<book category="children">
  <title lang="en">Harry Potter</title>
  <author>J K. Rowling</author>
  <year>2005</year>
  <price>29.99</price>
</book>

<book category="web">
  <title lang="en">XQuery Kick Start</title>
  <author>James McGovern</author>
  <author>Per Bothner</author>
  <author>Kurt Cagle</author>
  <author>James Linn</author>
  <author>Vaidyanathan Nagarajan</author>
  <year>2003</year>
  <price>49.99</price>
</book>

<book category="web">
  <title lang="en">Learning XML</title>
  <author>Erik T. Ray</author>
  <year>2003</year>
  <price>39.95</price>
</book>

</bookstore>

from which, i need to replace all values found in fileA.txt, with the ones found in fileB.txt

example of fileA.txt:

500
345
623
etc

values to be searched for

example of fileB.txt:

550
350
700
etc

so <price>500</price> should become <price>550</price>

I can run multiple times the below command,

sed -i 's/old/new/g' file.xml,

could you please show me a more clever way, in order to specify for example that the replacement must take only place in the tag, and that if i need to replace 500 with 600, then 5000 will not become 6000?

Perhaps a python script would be preferred?

As in the comments, could you show me a python way, since i may be using the wrong tools, for the task?

m0nhawk
  • 22,980
  • 9
  • 45
  • 73

2 Answers2

0

sed is probably the wrong tool, and yet if it was certain no other of those fileA.txt numbers exist in file.xml but those to be changed, this should work:

paste file[AB].txt | sed 's/^.*/s#\\b&/;s/.*$/&#g/;s/\t/\\b#/' | sed -f - file.xml

First paste puts fileA.txt and fileB.txt together:

500 550
345 350
623 700
etc etc

Then sed converts that into future sed substitute commands:

s#\b500\b#550#g
s#\b345\b#350#g
s#\b623\b#700#g
s#\betc\b#etc#g

After which those are piped to sed -f -, which runs those commands.

agc
  • 7,973
  • 2
  • 29
  • 50
0

You could do something like that with xmlstarlet. For example,

xmlstarlet ed -u //price[text()='30.00'] -v '32.00' bookstore.xml

would replace a price of 30.00 with a price of 32.00 in your example file. You could build a command line from files as demonstrated by agc, but it would be onerous.

Michael Vehrs
  • 3,293
  • 11
  • 10