6 votes

Utilisation de sed pour remplacer une chaîne de caractères spéciaux dans un fichier XML

J'ai des difficultés à faire en sorte que sed remplace une chaîne de texte dans un fichier XML, alors que je n'ai aucun problème à utiliser grep pour trouver cette même chaîne. Comme la nouvelle et l'ancienne chaîne à remplacer contiennent beaucoup de caractères spéciaux, j'ai pensé qu'il valait mieux les stocker dans des variables plutôt que d'utiliser une multitude de barres obliques inversées :

OLD_STRING='<property name="webServiceHost">${jboss.bind.address}</property>'
NEW_STRING='<!--<property name="webServiceHost">${jboss.bind.address}</property>-->'

Les chaînes de caractères semblent être stockées comme prévu :

$ echo $OLD_STRING; echo $NEW_STRING
<property name="webServiceHost">${jboss.bind.address}</property>
<!--<property name="webServiceHost">${jboss.bind.address}</property>-->

Le grep'ing confirme que l'ancienne chaîne est présente dans le fichier XML :

$ grep "$OLD_STRING" jboss-beans.xml
<property name="webServiceHost">${jboss.bind.address}</property>

Mais la commande sed suivante ne produit aucun résultat :

sed -i 's/"$OLD_STRING"/"$NEW_STRING"/g' jboss-beans.xml

Une idée de ce que j'ai manqué ici ?

3voto

Fraser Points 6783

Mettre les variables Shell entre guillemets simples désactive leur interprétation. C'est pourquoi votre commande n'a aucun effet.

$ echo  's/"$OLD_STRING"/"$NEW_STRING"/g'
s/"$OLD_STRING"/"$NEW_STRING"/g

Ça devrait être écrit comme ça :

sed -i "s/'$OLD_STRING'/'$NEW_STRING'/g" jboss-beans.xml

Mais alors les variables sont interprétées avant en appelant sed et les autres contiennent des caractères spéciaux :

$ echo  "s/'$OLD_STRING'/'$NEW_STRING'/g"
s/'<property name="webServiceHost">${jboss.bind.address}</property>'/'<!--<property name="webServiceHost">${jboss.bind.address}</property>-->'/g

C'est pourquoi sed a cette particularité de permettre de définir le s/// les délimiteurs de commande en les utilisant simplement, par exemple :

sed -i "s#'$OLD_STRING'#'$NEW_STRING'#g" jboss-beans.xml

Si votre expression de recherche contient des caractères spéciaux de regexp, et si vous utilisez la fonction sed comme ça, c'est juste un gaspillage de ses capacités. J'écrirais l'expression comme ceci :

sed -i 's/\(<.*webServiceHost.*jboss.bind.address.*>\)/<!--\1-->/' jboss-beans.xml

Bien entendu, vous pouvez rendre la chaîne de correspondance plus ou moins spécifique en fonction de vos besoins. Il existe également une autre fonctionnalité intéressante qui peut vous aider. sed permet de limiter les opérations d'édition aux lignes correspondant à un motif spécifique. Votre commande pourrait ressembler à ceci :

sed -i '/webServiceHost/ s/^\(.*\)$/<!--\1-->/' jboss-beans.xml

0voto

Magnus Points 86

Cela peut vous être utile :
Manipulation XML en ligne de commande
http://xmlstar.sourceforge.net/

AFAICR
apt-get install xmlstarlet

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X