2

I'm trying to write a script that processes .xml file. It has to find all lines with a <title> element, copy it, and paste in a next line after that found one, but also changing the element type. Here is an example.

Original:

some text
<title>text 1</title>
some text
<title>text 2</title>
some text

And this is what I need to get:

some text
<title>text 1</title>
<description>text 1</description>
some text
<title>text 2</title>
<description>text 2</description>
some text

Can it be done with sed or grep (or some other tool)?

2
  • why the second <title> line has text 1 in the result? a typo? Jul 11, 2017 at 22:02
  • yes, it was a typo, i've corrected it
    – xjr
    Jul 20, 2017 at 21:41

2 Answers 2

4

sed -E 's%<title>(.*)</title>%<title>\1</title>\n<desc>\1</desc>%g' file.xml should do your homework.

To explain it a bit further: -E parameter tells sed to use extended regular expressions, so you can use references. Replacing with sed is normally done in the form s/search/replace/g. As there are slashes in the search text we use % instead of / for sed to mark the parts, so we do not have to mask the slashes in the search text by a backslash. The rest is normal regex stuff, \1 in the replace part references the snippet inside (…) in the search part.

2
  • This answer needs explanation. Jul 12, 2017 at 22:09
  • Thank you, it works. I have not analyzed it yet, but it works!
    – xjr
    Jul 20, 2017 at 21:55
3

XML parsers/processors are the right tools for manipulating XML data.

xmlstarlet solution:

the exemplary input.xml content:

<root>
some text
<title>text 1</title>
some text
<title>text 2</title>
some text </root>

xmlstarlet ed -a '//title' -t elem -n 'description' -v '' input.xml \
 | xmlstarlet ed -u '//description' -x './preceding-sibling::title[1]/text()'

The output:

<?xml version="1.0"?>
<root>
some text
<title>text 1</title><description>text 1</description>
some text
<title>text 2</title><description>text 2</description>
some text </root>

  • ed - edit mode

  • -a - append action

  • -u - update action

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .