Reputation: 1173
I'm bashing my head against the wall with this one. How do I do a regex replacement with sed
on text that contains a newline?
I need to replace the value of the "version" XML element shown below. There are multiple version elements so I want to replace the one that comes after the "name" element.
<name>MyName</name>
<version>old</version>
Here's my command:
sed -i -E "s@(\s*<name>$NAME</name>\n\s*<version>)$VERSION_OLD(</version>)@\1$VERSION_NEW\2@g" $myfile.txt
Now as far as I know there is a way to make sed
work with a newline character, but I can't figure it out. I've already used sed in my script so ideally I'd prefer to re-use it instead of say perl
.
Upvotes: 0
Views: 1376
Reputation: 30968
If you're using GNU sed, you can use its extended addressing syntax:
sed '/<name>/,+1{/<version>/s/old/newer/}' file
Breaking this down, it says: for a line matching <name>
and the following line (+1
), then if the line matches <version>
, substitute old
with newer
.
I'm assuming here that your file is generated, and will always have the name
and version
elements each on a single line, and adjacent. If you need to handle more free-form XML, then you should really consider an XPath-based tool rather than sed.
Upvotes: 0
Reputation: 88929
When you see your name
element, you will need to use the N
command to read the next line:
file:
<bar>MyName</bar>
<version>old</version>
<name>MyName</name>
<version>old</version>
<foo>MyName</foo>
<version>old</version>
With GNU sed:
sed '/<name>/{N;s/old/newer/}' file
Output:
<bar>MyName</bar>
<version>old</version>
<name>MyName</name>
<version>new</version>
<foo>MyName</foo>
<version>old</version>
Upvotes: 3