是否可以使用sed替换pom文件中的依赖项版本?

时间:2016-01-22 23:24:44

标签: regex bash maven sed

我有一个pom.xml文件,我想将dependency0.1-SNAPSHOT节点内的版本替换为另一个版本(让我们说{{1} }),我唯一的限制是只有当NEW-VERSION与特定文本匹配时才应该进行替换,让我们说:groupId

话虽如此,让我们说这是我com.company.xyz的{​​{1}}部分:

dependencies

应用sed命令后,我希望它看起来像:

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>

我想知道这不起作用的原因是因为我的文本有多行,所以我研究了一下但是我不理解用于处理多行的语法(一些<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> 事物)

顺便说一下,我将这段代码包含在执行其他操作的bash文件中,这就是为什么我要使用sed或任何其他&#34;工具&#34;这是bash兼容的。

4 个答案:

答案 0 :(得分:2)

这是一个sed解决方案 - 比awk稍微笨拙,但并非如此糟糕。如果您将其存储在文件中,例如sedscr

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

您可以使用sed -i sedscr pom.xml运行它。这是它的工作原理:

/<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/
    }
}

你的sed没有用,因为你尝试匹配换行符,但sed在其模式空间中一次只有一行 - 除非你开始使用像N这样的命令(&#34; Next& #34)。即使你在模式空间中有多行,你也必须考虑新行并将它们与\n匹配(并处理空白等)。

您可以在Bash脚本中使用它,如下所示:

#!/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

当sed命令不在单引号内时,这样的引用可以避免潜在的麻烦;只有$new_version是双引号才允许插值。

答案 1 :(得分:1)

我建议使用maven属性,这些属性很清楚,并且使用sed搜索和替换时很容易处理。

所以pom.xml看起来像:

<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>

更改版本的命令行将是:

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

答案 2 :(得分:0)

gnu-awk与自定义RS(记录分隔符)套件更好:

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

awk命令分手

-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

简而言之,这个awk命令将输入​​数据分成记录,作为在</dependency>之前包含多行的部分,然后使用groupId函数检查所需index是否存在,并使用{{替换文本1}}功能。

<强>输出:

sub

答案 3 :(得分:0)

以下awk程序已经使用gawk和mawk进行了测试,使用本页其他地方给出的RS简化和概括了awk程序。通过使用printf,它们还可以确保间距保持不变。

(a)简化

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

(b)简化与概括

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