我有一个pom.xml
文件,我想将dependency
个0.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兼容的。
答案 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}'