Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use Sed to replace next line but keep the white space

Tags:

linux

sed

I'm using this answer here: https://stackoverflow.com/a/18622953/1797263 to replace a version in a pom.xml file. The problem I'm running into is that it is stripping the preceding whitespace and I want to keep the preceding whitespace. The whitespace could be 2 or 3 tabs or spaces, depending on how the developer formatted the file.

Here is an example:

        <dependency>
            <groupId>GROUP</groupId>
            <artifactId>ARTIFACT</artifactId>
            <version>OLD_VERSION</version>
        </dependency>

My command: sed -i '/<artifactId>ARTIFACT<\/artifactId>/!b;n;c<version>NEW_VERSION</version>' pom.xml

And my output:

        <dependency>
            <groupId>GROUP</groupId>
            <artifactId>ARTIFACT</artifactId>
<version>NEW_VERSION</version>
        </dependency>

Here is what I would like the replacement to look like:

        <dependency>
            <groupId>GROUP</groupId>
            <artifactId>ARTIFACT</artifactId>
            <version>NEW_VERSION</version>
        </dependency>

I read through the GNU Sed manual and could not find anything that would help.

like image 675
Chris Savory Avatar asked Dec 04 '25 00:12

Chris Savory


1 Answers

Using a proper xml parser :

xmlstarlet edit -L -u '/dependency/version' -v NEW_VERSION file.xml

 Output

<?xml version="1.0"?>
<dependency>
  <groupId>GROUP</groupId>
  <artifactId>ARTIFACT</artifactId>
  <version>NEW_VERSION</version>
</dependency>

Don't parse XML/HTML with regex, use a proper XML/HTML parser and a powerful xpath query.

theory :

According to the compiling theory, XML/HTML can't be parsed using regex based on finite state machine. Due to hierarchical construction of XML/HTML you need to use a pushdown automaton and manipulate LALR grammar using tool like YACC.

realLife©®™ everyday tool in a shell :

You can use one of the following :

xmllint often installed by default with libxml2, xpath1 (check my wrapper to have newlines delimited output

xmlstarlet can edit, select, transform... Not installed by default, xpath1

xpath installed via perl's module XML::XPath, xpath1

xidel xpath3

saxon-lint my own project, wrapper over @Michael Kay's Saxon-HE Java library, xpath3

or you can use high level languages and proper libs, I think of :

python's lxml (from lxml import etree)

perl's XML::LibXML, XML::XPath, XML::Twig::XPath, HTML::TreeBuilder::XPath

ruby nokogiri, check this example

php DOMXpath, check this example


Check: Using regular expressions with HTML tags

enter image description here

like image 96
Gilles Quenot Avatar answered Dec 06 '25 14:12

Gilles Quenot



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!