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 customRS
(记录分隔符)更好地满足这一要求:
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)