Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 是否可以使用sed替换依赖项';pom文件中的版本?_Regex_Bash_Maven_Sed - Fatal编程技术网

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

Regex 是否可以使用sed替换依赖项';pom文件中的版本?,regex,bash,maven,sed,Regex,Bash,Maven,Sed,我有一个pom.xml文件,我想将dependency节点内的版本从0.1-SNAPSHOT替换为另一个版本(比如NEW-version),唯一的限制是,仅当groupId匹配特定文本时才应进行替换,比如说:com.company.xyz 话虽如此,假设这是我的pom.xml的依赖项部分: <dependencies> <dependency> <groupId>com.company.xyz</groupId&g

我有一个
pom.xml
文件,我想将
dependency
节点内的版本从
0.1-SNAPSHOT
替换为另一个版本(比如
NEW-version
),唯一的限制是,仅当
groupId
匹配特定文本时才应进行替换,比如说:
com.company.xyz

话虽如此,假设这是我的
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>

com.company.xyz
xyz-xx-utils
0.1-1快照
com.ibm.xyz
xyz
56.1
应用sed命令后,我希望它看起来像:

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

com.company.xyz
xyz-xx-utils
新版本
com.ibm.xyz
xyz
56.1
以下是我尝试过但没有成功的方法:

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
newVersion=“新版本”
sed-i“s/\(\)\(com.company.xyz\)\(.\\)\(0.1-SNAPSHOT\)\(\)/\1\2\3$newVersion\5/“pom.xml
我想知道这不起作用的原因是否是因为我的文本有多行,所以我进行了一些研究,但我不了解用于处理多行的语法(一些
N
事情)


顺便说一句,我将这段代码包含在一个执行其他操作的bash文件中,这就是为什么我希望使用sed或任何其他与bash兼容的“工具”来执行此操作。

gnu awk with custom
RS
(记录分隔符)更好地满足这一要求:

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

带有自定义
RS
(记录分隔符)的gnu awk更适合:

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

这是一个sed解决方案——比awk稍微笨拙一点,但并不可怕。如果将其存储在文件中,例如,
sedscr

/<dependency>/ {
    :start
    N
    /<\/dependency>$/!b start
    /<groupId>com.company.xyz<\/groupId>/ {
        s/\(<version>\)0\.1-SNAPSHOT\(<\/version>\)/\1NEW-VERSION\2/
    }
}
您的sed不起作用,因为您试图跨换行符进行匹配,但sed在其模式空间中一次只有一行,除非您开始使用类似于
N
(“Next”)的命令。即使在模式空间中有多行,也必须考虑换行符并将其与
\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
#/bin/bash
新版本=“新版本”
sed'//{
:开始
N
/$/!b开始
/com.company.xyz/{
s/\(\)0\.1-快照\(\)/\1'$new\u version'\2/
}
}'pom.xml

这样引用避免了sed命令不在单引号内时的潜在问题;只有
$new\u版本
在双引号中允许插值。

这是一个sed解决方案-比awk稍微笨拙一些,但也不可怕。如果将其存储在文件中,例如,
sedscr

/<dependency>/ {
    :start
    N
    /<\/dependency>$/!b start
    /<groupId>com.company.xyz<\/groupId>/ {
        s/\(<version>\)0\.1-SNAPSHOT\(<\/version>\)/\1NEW-VERSION\2/
    }
}
您的sed不起作用,因为您试图跨换行符进行匹配,但sed在其模式空间中一次只有一行,除非您开始使用类似于
N
(“Next”)的命令。即使在模式空间中有多行,也必须考虑换行符并将其与
\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
#/bin/bash
新版本=“新版本”
sed'//{
:开始
N
/$/!b开始
/com.company.xyz/{
s/\(\)0\.1-快照\(\)/\1'$new\u version'\2/
}
}'pom.xml

这样引用避免了sed命令不在单引号内时的潜在问题;只有
$new\u version
在双引号中,以允许插值。

以下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}'
awk-v RS=“”/com.company.xyz/{
sub(/0\.1-SNAPSHOT/,“新版本”)}{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}'
awk-v groupId=“com.company.xyz”-v RS=”“'
$0~“”组ID“”{
子(“新版本”)
} 
{printf“%s”,$0 RS}

以下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}'
awk-v RS=“”/com.company.xyz/{
sub(/0\.1-SNAPSHOT/,“新版本”)}{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}'
awk-v groupId=“com.company.xyz”-v RS=”“'
$0~“”组ID“”{
子(“新版本”)
} 
{printf“%s”,$0 RS}

我建议使用maven属性,这些属性很清晰,而且很容易通过sed搜索和替换进行处理

所以pom.xml看起来像:

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

2
com.company.xyz
xyz-xx-utils
${xyz xx utils.version}
更改版本的命令行将为:

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

我建议使用maven属性,这些属性很清晰,而且很容易通过sed搜索和替换进行处理

所以pom.xml看起来像:

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

2
com.company.xyz
xyz-xx-utils
${xyz xx utils.version}
更改版本的命令行将为:

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

非常感谢@anubhava!请你解释一下代码好吗?我还注意到控制台中的输出非常完美,但是实际文件没有改变,你知道为什么吗?想法是将sed的输出重定向到一个文件。默认情况下,它会像unix工具一般那样打印到标准输出。尝试使用
sed-i
。感谢您的建议@TrentBartlem,我正在使用anubhava提供的代码(它使用awk而不是sed),我稍微修改了一下,将输出发送到如下文件:awk-v RS=“”'index($0,“com.company.xyz”){sub(/0\.1-SNAPSH)