2015-12-28 3 views
1

У меня есть config.xml образец файл, который выглядит следующим образом:СЕПГ команды заменить второе вхождение тегов XML

<maven2-moduleset> 
    <actions/> 
    <jdk>JDK 6 Update 26</jdk> 
    <publishers> 
    <hudson.plugins.sonar.SonarPublisher plugin="[email protected]"> 
     <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.

ответ

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 

Это работает, потому что только второй экземпляр в вашем примере не хватает пространства.

Наконец, вы могли бы сказать СЕПГ только заменить jdk тега, который появляется между hudson тегами:

sed -i "/<hudson/,/<\/hudson/ s#<jdk>.*</jdk>#<jdk>jdk1.7.0_76</jdk>#" config.xml 

Я использовал # вместо / для поиска разделителя, потому что в отличие от / он не появляется в регулярное выражение.

+0

Плюс один для предложения, как писать строгие правила. (например, 'jdk [0-9.] *' вместо '. *') & «совпадение только между hudson» было хорошим. – anishsane

+0

так хорошо объяснил @julian. Благодарю. Оно работало завораживающе. –

0

Для этого конкретного случая, вы можете использовать эту команду SED:

sed -i "s/<jdk>jdk.*<\/jdk>/<jdk>jdk1.7.0_76<\/jdk>/g" config.xml 

Это должно заменить любую jdk[version] строки в JDK тегов XML с вашей собственной версией 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 

Он ищет второе совпадение XML-тегов <jdk></jdk>, а затем заменяет версию.

+0

Я знаю, что вы больше сосредоточены на решении проблемы с awk, но ваше решение sed не решит проблему для ввода образца из-за ведущих пробелов во вводе и использования вами^в решении. – Julian

Смежные вопросы