J'essaie d'extraire une valeur d'un document XML qui a été lue dans mon script en tant que variable. La variable d'origine, $ data, est la suivante:
<item>
<title>15:54:57 - George:</title>
<description>Diane DeConn? You saw Diane DeConn!</description>
</item>
<item>
<title>15:55:17 - Jerry:</title>
<description>Something huh?</description>
</item>
et je souhaite extraire la valeur du premier titre, donc
15:54:57 - George:
J'ai utilisé la commande sed:
title=$(sed -n -e 's/.*<title>\(.*\)<\/title>.*/\1/p' <<< $data)
mais cela ne donne que la deuxième valeur de titre:
15:55:17 - Jerry:
Est-ce que quelqu'un sait ce que j'ai mal fait? Merci!
Comme Charles Duffey a déclaré, les analyseurs XML sont mieux analysés avec des outils d'analyse XML appropriés. Pour un travail ponctuel, ce qui suit devrait fonctionner.
grep -oPm1 "(?<=<title>)[^<]+"
$ echo "$data"
<item>
<title>15:54:57 - George:</title>
<description>Diane DeConn? You saw Diane DeConn!</description>
</item>
<item>
<title>15:55:17 - Jerry:</title>
<description>Something huh?</description>
$ title=$(grep -oPm1 "(?<=<title>)[^<]+" <<< "$data")
$ echo "$title"
15:54:57 - George:
XMLStarlet ou un autre moteur XPath est l'outil approprié pour ce travail.
Par exemple, avec data.xml
contenant les éléments suivants:
<root>
<item>
<title>15:54:57 - George:</title>
<description>Diane DeConn? You saw Diane DeConn!</description>
</item>
<item>
<title>15:55:17 - Jerry:</title>
<description>Something huh?</description>
</item>
</root>
... vous pouvez extraire uniquement le premier titre avec les éléments suivants:
xmlstarlet sel -t -m '//title[1]' -v . -n <data.xml
Essayer d'utiliser sed pour ce travail est compliqué . Par exemple, les approches basées sur les expressions rationnelles ne fonctionneront pas si le titre a des attributs; ne gérera pas les sections CDATA; ne reconnaîtra pas correctement les mappages d'espace de noms; ne peut pas déterminer si une partie du XML documenté est commentée; ne déchaînera pas les références d'attribut (comme changer Brewster & Jobs
à Brewster & Jobs
), et ainsi de suite.
Je suis d'accord avec Charles Duffy pour dire qu'un analyseur syntaxique XML approprié est la bonne solution.
Mais quant à ce qui ne va pas avec votre commande sed
(ou l'avez-vous fait exprès?).
$data
n'a pas été cité, donc $data
est soumis au fractionnement de Word de Shell, à l’extension du nom de fichier, entre autres. L'une des conséquences est que l'espacement dans l'extrait de code XML n'est pas préservé.Donc, étant donné votre structure XML spécifique, cette commande modifiée sed
devrait fonctionner
title=$(sed -ne '/title/{s/.*<title>\(.*\)<\/title>.*/\1/p;q;}' <<< "$data")
Essentiellement, pour la ligne contenant title
, extrayez le texte entre les balises, puis quittez (pour ne pas extraire le 2nd <title>
)