Search code examples
xmlshellawksedxmlstarlet

Using awk/sed to parse/replace XML inline


I'm trying to modify multiple version numbers from a pom.xml file in a single shell script, where I'm unsure of what the version number of the component may be. I can parse down to version, however, cannot replace that version inline.

The pom.xml looks something like this:

...
        <dependency>
            <groupId>abc.efg</groupId>
            <artifactId>service1</artifactId>
            <version>0.0.10</version>
        </dependency>
        <dependency>
            <groupId>abc.efg</groupId>
            <artifactId>service2</artifactId>
            <version>0.1.5</version>
        </dependency>
        <dependency>
            <groupId>abc.efg</groupId>
            <artifactId>service3</artifactId>
            <version>0.0.1</version>
        </dependency>
...

I'm completely new to shell scripting so forgive me if this is a little sloppy, but this far I can pull the service version stringing grep like;

$ grep -A 1 "service1" pom.xml | grep -Eo '[.0-9]*'
$ 0.0.10

but using awk to replace inline is proving challenging

$ grep -A 1 "service" pom.xml | grep -Eo '[.0-9]*' | sed 's/[,0-9]/3.2.1/g'
$ 3.2.1.3.2.1.3.2.1

Output I'm looking for is:

0.0.10 -> 3.2.1

$ grep -A 1 "service" pom.xml | grep -Eo '[.0-9]*' | #sedsyntax
$ 3.2.1

Any advice or pointers would be appreciated at this point


Solution

  • You can do it all at once with sed. Search for the pattern, go to next line , replace the version number.

    $ sed -r '/service1/!b;n;s/([0-9][.]?)+/1.1.11/' file
    <xml>
      <dependency>
        <groupId>abc.efg</groupId>
        <artifactId>service1</artifactId>
        <version>1.1.11</version>
      </dependency>
      <dependency>
        <groupId>abc.efg</groupId>
        <artifactId>service2</artifactId>
        <version>0.1.5</version>
      </dependency>
      <dependency>
        <groupId>abc.efg</groupId>
        <artifactId>service3</artifactId>
        <version>0.0.1</version>
      </dependency>
    </xml>
    

    Explanation:

    sed -r '/service1/!b;n;s/([0-9][.]?)+/1.1.11/' file
            |________||___||_____________________|      
                |       |               |
    Pattern-----|       |               |
    Go next line--------|               |
    Replace Operation-------------------|
    -r switch (or -E) = Extended Regexp Support