简体   繁体   中英

Using sed with a newline in a regex

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 .

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>

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM