我有一个示例config.xml文件,如下所示:
<maven2-moduleset>
<actions/>
<jdk>JDK 6 Update 26</jdk>
<publishers>
<hudson.plugins.sonar.SonarPublisher plugin="sonar@2.1">
<jdk>jdk1.8</jdk>
</hudson.plugins.sonar.SonarPublisher>
</publishers>
</maven2-moduleset>
我想更改<jdk></jdk>
标记的第二次出现。所以我使用sed命令来做到这一点,如下所示:
sed -i "s/<jdk>\.*<\/jdk>/<jdk>jdk1.7.0_76<\/jdk>/2" config.xml
但该文件没有变化。我哪里错了?
注意:第二次出现的jdk标签可以包含任何jdk版本。我想将该标记中提到的任何值(版本)替换为此值=“jdk1.7.0_76”。 和, 我不能使用perl或xmlstarlet。
答案 0 :(得分:3)
您的模式将在标签之间的任意数量的文字.
上匹配文字,就是这样,这不是您想要的。此外,您要附加2,因为您希望匹配jdk
标记对的第二次出现,但这只有在您的两对jdk
标记出现在同一行时才有效。
如果你想匹配jdk
标签之间某个时间段的任何内容,那么这将有效:
sed -i "s#<jdk>.*\..*</jdk>#<jdk>jdk1.7.0_76</jdk>#" config.xml
这只会替换第二个jdk
标记对,因为第一个不包含.
,它在上面的正则表达式中与\.
匹配。
您还可以匹配任何不包含空格的内容:
sed -i "s#<jdk>[^ ]*</jdk>#<jdk>jdk1.7.0_76</jdk>#" config.xml
这是有效的,因为只有示例中的第二个实例缺少空格。
最后,您可以告诉sed仅替换jdk
代码之间显示的hudson
代码:
sed -i "/<hudson/,/<\/hudson/ s#<jdk>.*</jdk>#<jdk>jdk1.7.0_76</jdk>#" config.xml
我使用#
代替/
作为搜索分隔符,因为与/
不同,它不会出现在正则表达式中。
答案 1 :(得分:0)
对于这种特定情况,您可以使用此sed命令:
sed -i "s/<jdk>jdk.*<\/jdk>/<jdk>jdk1.7.0_76<\/jdk>/g" config.xml
这应该用你自己的jdk版本替换jdk xml标签中的任何jdk[version]
字符串。
但是,我建议你使用awk
来做。
这应该可以解决问题:
awk '/<jdk>.*<\/jdk>/{c+=1}{if(c==2){sub("<jdk>.*</jdk>","<jdk>jdk.1.7.0_76</jdk>",$0)};print}' config.xml > config_new.xml
它查找<jdk></jdk>
xml标签的第二次出现,然后替换该版本。