我有一个示例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版本。我希望将该标记中提到的任何值(版本)替换为这个value="jdk1.7.0_76“。而且,我不能使用perl或xmlstarlet。
发布于 2015-12-28 09:44:56
您的模式将匹配标记之间任意数量的文字.,仅此而已,这不是您想要的。另外,您要追加一个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我使用#而不是/作为搜索分隔符,因为与/不同,它不会出现在regex中。
发布于 2015-12-28 09:52:04
对于这种特殊情况,可以使用以下sed命令:
sed -i "s/<jdk>jdk.*<\/jdk>/<jdk>jdk1.7.0_76<\/jdk>/g" config.xml这应该将jdk标记中的任何jdk[version]字符串替换为您自己的jdk版本。
但是,我建议你用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>标记的第二次出现,然后替换版本。
https://stackoverflow.com/questions/34490761
复制相似问题