Is it possible to use sed to replace dependencies's version in a pom file?

旧时模样 提交于 2021-01-28 12:12:42

问题


I have a pom.xml file and I want to replace the version inside any of the dependency nodes from 0.1-SNAPSHOT to a different version (let's say NEW-VERSION), the only restriction I have is that the replacement should be done only if the groupId matches a particular text, lets say: com.company.xyz.

That being said, let's say this is the dependencies section of my pom.xml:

<dependencies>
        <dependency>
            <groupId>com.company.xyz</groupId>
            <artifactId>xyz-xx-utils</artifactId>
            <version>0.1-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>com.ibm.xyz</groupId>
            <artifactId>xyz</artifactId>
            <version>56.1</version>
        </dependency>
</dependencies>

After applying the sed command I want it to look like:

<dependencies>
        <dependency>
            <groupId>com.company.xyz</groupId>
            <artifactId>xyz-xx-utils</artifactId>
            <version>NEW-VERSION</version>
        </dependency>

        <dependency>
            <groupId>com.ibm.xyz</groupId>
            <artifactId>xyz</artifactId>
            <version>56.1</version>
        </dependency>
</dependencies>

Here is what I have tried without any success:

newVersion="NEW-VERSION"

sed -i "s/\(<dependency>\)\(<groupId>com.company.xyz</groupId>\)\(<artifactId>.*\</artifactId>\)\(<version>0.1-SNAPSHOT</version>\)\(</dependency>\)/\1\2\3$newVersion\5/" pom.xml

I was wondering if the reason why this does not work is because my text has multiple lines, so I researched a little bit but I did not understand the syntax used to work with multiple lines (some N thing).

Btw, I am including this piece of code in a bash file that performs other operations, that is why I want to do this using sed or any other "tool" that is bash compatible.


回答1:


gnu-awk with custom RS (record separator) suites this better:

awk -v RS="</dependency>" 'index($0, "<groupId>com.company.xyz</groupId>"){
    sub(/0\.1-SNAPSHOT/, "NEW-VERSION")} RT{$0 = $0 RT} 1' file

Awk command breakup

-v RS="</dependency>"               # sets input record separator as </dependency>
index($0, "<groupId>...")           # for lines that have give string
sub(/0\.1-SNAPSHOT/, "NEW-VERSION") # replace 0.1-SNAPSHOT by NEW-VERSION
1                                   # default action to print the line

In short this awk command breaks input data into records as section containing multiple lines before </dependency> and then checks for presence of desired groupId using index function and replaces the text using sub function.

Output:

<dependencies>
        <dependency>
            <groupId>com.company.xyz</groupId>
            <artifactId>xyz-xx-utils</artifactId>
            <version>NEW-VERSION</version>
        </dependency>


        <dependency>
            <groupId>com.ibm.xyz</groupId>
            <artifactId>xyz</artifactId>
            <version>56.1</version>
        </dependency>

</dependencies>



回答2:


This is a sed solution – a little more unwieldy than awk, but not horribly so. If you store this in a file, say, sedscr:

/<dependency>/ {
    :start
    N
    /<\/dependency>$/!b start
    /<groupId>com.company.xyz<\/groupId>/ {
        s/\(<version>\)0\.1-SNAPSHOT\(<\/version>\)/\1NEW-VERSION\2/
    }
}

You can run it with sed -i sedscr pom.xml. This is how it works:

/<dependency>/ {   # If the line matches "<dependency>"
    :start         # Label to branch to
    N              # Append next line to pattern space

    # If the pattern space does not end with "</dependency>", branch to start
    /<\/dependency>$/!b start

    # We now have the complete <dependency> element in the pattern space

    # If the groupId element matches "com.company.xyz"
    /<groupId>com.company.xyz<\/groupId>/ {

        # Substitute the version for "NEW-VERSION"
        s/\(<version>\)0\.1-SNAPSHOT\(<\/version>\)/\1NEW-VERSION\2/
    }
}

Your sed didn't work because you try to match across newlines, but sed only has one line at a time in its pattern space – unless you start using commands like N ("Next"). Even when you do have multiple lines in pattern space, you have to account for newlines and match them with \n (and take care of whitespace and so on).

You could use this in a Bash script as follows:

#!/bin/bash

new_version='NEW-VERSION'

sed '/<dependency>/ {
    :start
    N
    /<\/dependency>$/!b start
    /<groupId>com.company.xyz<\/groupId>/ {
        s/\(<version>\)0\.1-SNAPSHOT\(<\/version>\)/\1'"$new_version"'\2/
    }
}' pom.xml

Quoting like this avoids potential trouble when the sed commands are not within single quotes; only $new_version is in double quotes to allow for interpolation.




回答3:


I would recommend using maven properties which are clear and accidentally easy to process with sed search and replace.

So pom.xml will look like:

<properties>
    <xyz-xx-utils.version>2.0</xyz-xx-utils.version>
</properties>
<dependencies>
    <dependency>
        <groupId>com.company.xyz</groupId>
        <artifactId>xyz-xx-utils</artifactId>
        <version>${xyz-xx-utils.version}</version>
    </dependency>
</dependencies>

Command line to change the version will be:

sed -i.bak  "s/<xyz-xx-utils.version>.*<\/xyz-xx-utils.version>/<xyz-xx-utils.version>NEW-VERSION<\/xyz-xx-utils.version>/g"  $pomfile



回答4:


The following awk programs, which have been tested with gawk and mawk, simplify and generalize the awk program using RS given elsewhere on this page. By using printf, they also ensure spacing is preserved.

(a) simplification

awk -v RS="</dependency>" '/<groupId>com.company.xyz<\/groupId>/ {
  sub(/0\.1-SNAPSHOT/, "NEW-VERSION")} {printf "%s", $0 RS}'

(b) simplification with generalization

awk -v groupId="com.company.xyz" -v RS="</dependency>" '
  $0 ~ "<groupId>" groupId "</groupId>" {
    sub("<version>.*</version>", "<version>NEW-VERSION</version>")
  } 
  {printf "%s", $0 RS}'


来源:https://stackoverflow.com/questions/34957616/is-it-possible-to-use-sed-to-replace-dependenciess-version-in-a-pom-file

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!