#1 Le 19/11/2017, à 09:53
- ShellNoob
[Résolu] SED / AWK pour récupérer variable dans fichier de conf XML
Bonjour à tous,
Je sollicites votre aide car je voudrais récupérer une variable dans un fichier de configuration et avec les caractères spéciaux (balise type XML), je n'arrives pas à extraire la chaîne de caractère après le =
Je commences par isoler la ligne qui m'intéresse et je l'exporte dans un fichier
grep 'ThemeSet' /recalbox/share/system/.emulationstation/es_settings.cfg > theme.txt
Le contenu du fichier de conf est donc le suivant
more theme.txt
<string name="ThemeSet" value="recalbox" />
je voudrais exporter dans une variable ce que contient value
L'idée serait d'obtenir ça
echo $NOM_THEME=recalbox
----------
J'ai essayé de faire un SED mais je n'arrives pas à supprimer les caractère /> en fin de ligne
variable_theme=$(sed -rn 's/^\value*=*"([^"]+)"/\1/p' theme.txt)
echo nom_theme="$variable_theme"
ça me retourne
echo $NOM_THEME=recalbox />
Merci par avance pour votre aide
Dernière modification par ShellNoob (Le 19/11/2017, à 12:49)
Hors ligne
#2 Le 19/11/2017, à 10:01
- Zakhar
Re : [Résolu] SED / AWK pour récupérer variable dans fichier de conf XML
C'est un fichier purement XML, ou une soupe avec du XML au milieu ?
"A computer is like air conditioning: it becomes useless when you open windows." (Linus Torvald)
Hors ligne
#3 Le 19/11/2017, à 10:08
- ShellNoob
Re : [Résolu] SED / AWK pour récupérer variable dans fichier de conf XML
Bonjour Zakhar,
C'est purement un fichier XML avec les balises formatées comme ça
<?xml version="1.0"?>
<config>
<string name="ThemeSet" value="recalbox" />
<string name="UpdateVersionFile" value="/recalbox/share/system/upgrade/recalbox.version.update" />
<string name="VersionFile" value="/recalbox/recalbox.version" />
</config>
Modération : merci d'utiliser les balises code (explications ici).
Dernière modification par cqfd93 (Le 19/11/2017, à 10:09)
Hors ligne
#4 Le 19/11/2017, à 10:23
- pingouinux
Re : [Résolu] SED / AWK pour récupérer variable dans fichier de conf XML
Bonjour,
variable_theme=$(sed -rn '/ThemeSet/s/.*value="([^"]+)".*/\1/p' fichier_xml)
echo nom_theme="$variable_theme"
Hors ligne
#5 Le 19/11/2017, à 10:43
- ShellNoob
Re : [Résolu] SED / AWK pour récupérer variable dans fichier de conf XML
Wahoou! Un grand merci pingouinux!!!
ça marche nickel! et dire que ça faisait des heures que je testais des commandes sed dans tous les sens!
Si je peu abuser de ton savoir, j'ai un autre besoin sur ce fichier pour un autre script.
Au lieu de récupérer simplement value="recalbox", je voudrais faire un rechercher/remplacer
Exemple:
Avant
value="recalbox"
Après
value="recalbox_custom"
Hors ligne
#6 Le 19/11/2017, à 11:04
- Zakhar
Re : [Résolu] SED / AWK pour récupérer variable dans fichier de conf XML
Si c'est purement du XML, une transformation XSLT est bien plus fiable, bien que le sed de Pingo soit fonctionnel.
Soit ton fichier: file.xml
$ cat file.xml
<?xml version="1.0"?>
<config>
<string name="ThemeSet" value="recalbox" />
<string name="UpdateVersionFile" value="/recalbox/share/system/upgrade/recalbox.version.update" />
<string name="VersionFile" value="/recalbox/recalbox.version" />
</config>
Voici file.xsl
$ cat file.xsl
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
<xsl:template match="/">
<xsl:apply-templates select="config/string[@name='ThemeSet']"/>
</xsl:template>
<xsl:template match="string">
<xsl:value-of select="@value"/>
</xsl:template>
</xsl:stylesheet>
Et la magie:
$ xsltproc file.xsl file.xml
recalbox
Maintenant, si la sortie désirée est aussi du xml, évidemment xslt est largement plus indiqué que sed
Dis ce que tu veux faire au juste et je te donne un exemple de XSLT.
Dernière modification par Zakhar (Le 19/11/2017, à 11:24)
"A computer is like air conditioning: it becomes useless when you open windows." (Linus Torvald)
Hors ligne
#7 Le 19/11/2017, à 11:07
- ShellNoob
Re : [Résolu] SED / AWK pour récupérer variable dans fichier de conf XML
Je ne suis pas très calé en XML.
XSLT permet de remettre en forme les balises XML pour les parser plus facilement c'est ça?
Hors ligne
#8 Le 19/11/2017, à 11:25
- Zakhar
Re : [Résolu] SED / AWK pour récupérer variable dans fichier de conf XML
Oui, voir exemple ci-dessus en modification de mon post.
Si tu veux faire du xml ==> xml, XSLT est fait pour ça, c'est l'outil idéal !..
XSLT peut en théorie tout faire (turing complete), mais là où il excelle vraiment c'est faire du xml vers xml. D'où le nom : on part d'un XML, on applique une Transformation, et on obtient un XML transformé en sortie.
Dans l'exemple ci-dessus on est obligé de le "tordre" un peu pour qu'il crache du texte pur avec la première directive pour lui dire qu'on ne veut que du texte sans le préliminaire xml.
C'est dommage qu'il soit aussi verbeux, ce qui en rebute plus d'un, parce que sinon c'est un langage génial, pur "fonctionnel".
Dernière modification par Zakhar (Le 19/11/2017, à 11:29)
"A computer is like air conditioning: it becomes useless when you open windows." (Linus Torvald)
Hors ligne
#9 Le 19/11/2017, à 11:38
- Zakhar
Re : [Résolu] SED / AWK pour récupérer variable dans fichier de conf XML
Voila, si tu veux changer juste 'recalbox' sur le 'string' dont le 'name' est 'ThemeSet'
$ cat file.xsl
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/config/string[@name='ThemeSet']">
<string name="ThemeSet" value="recalbox_custom" />
</xsl:template>
</xsl:stylesheet>
$ xsltproc file.xsl file.xml
<?xml version="1.0"?>
<config>
<string name="ThemeSet" value="recalbox_custom"/>
<string name="UpdateVersionFile" value="/recalbox/share/system/upgrade/recalbox.version.update"/>
<string name="VersionFile" value="/recalbox/recalbox.version"/>
</config>
En fait dans le XSL, tout le début dit juste qu'on recopie tout à l'identique.
On "capture" juste dans le dernier template le truc qu'on veut changer, et on écrit ce qu'on veut y mettre à la place.
C'est-y pas beau et propre !
"A computer is like air conditioning: it becomes useless when you open windows." (Linus Torvald)
Hors ligne
#10 Le 19/11/2017, à 12:06
- pingouinux
Re : [Résolu] SED / AWK pour récupérer variable dans fichier de conf XML
Au lieu de récupérer simplement value="recalbox", je voudrais faire un rechercher/remplacer
Exemple:
Avant
value="recalbox"Après
value="recalbox_custom"
Avec sed :
sed -r '/ThemeSet/s/(.*value=")[^"]+(".*)/\1recalbox_custom\2/' fichier_xml >fichier_xml_modifie
ou, pour modifier directement le fichier d'origine, si tu es sûr de ton coup
sed -ri '/ThemeSet/s/(.*value=")[^"]+(".*)/\1recalbox_custom\2/' fichier_xml
Hors ligne
#11 Le 19/11/2017, à 12:57
- ShellNoob
Re : [Résolu] SED / AWK pour récupérer variable dans fichier de conf XML
Un grand merci à vous deux pour les solutions proposées.
Grâce à vous, je vais pouvoir apporter ma petite pierre à la distrib Recalbox dédié au retrogaming. (projet sur github)
Les info que vous m'avez fournit vont me permettre de terminer mes scripts pour créer des profils de joueurs et switcher les configurations personnaliser (ex: thème, vidéo d'intro, mappage manette de jeux, émulateurs)
J'aime bien le faire avec SED, c'est efficace et simple à intégrer dans mes scripts.
Je me pencherais cependant sur XSLT ça pourra sans doute me servir.
Hors ligne
#12 Le 19/11/2017, à 13:01
- Zakhar
Re : [Résolu] SED / AWK pour récupérer variable dans fichier de conf XML
sed est effectivement plus "habituel" qu'un langage fonctionnel qui est assez déroutant quand on commence.
Pour des petites tâches sed est sans doute plus performant qu'une transformation XSLT, mais c'est aussi largement plus casse gueule. Il suffit qu'il y ait d'autres choses sur la ligne, genre des commentaires, ou des quotes escapées... et ça va largement se compliquer.
Bien sûr si le fichier d'origine est généré par un programme, c'est en général plus "stable" et sed est une façon quick & dirty, mais néanmoins efficace de traiter la chose.
Exemple tout bête de ce que je raconte, modifions légèrement le fichier d'entrée ainsi :
$ cat file.xml
<?xml version="1.0"?>
<config>
<string name="ThemeSet"
value="recalbox" />
<string name="UpdateVersionFile" value="/recalbox/share/system/upgrade/recalbox.version.update" />
<string name="VersionFile" value="/recalbox/recalbox.version" />
</config>
Pour xml, qu'il y ait une espace ou un saut de ligne entre deux attributs ne change strictement rien d'un point de vue formel.
Avec sed on n'obtient plus du tout le résultat escompté:
$ sed -r '/ThemeSet/s/(.*value=")[^"]+(".*)/\1recalbox_custom\2/' file.xml
<?xml version="1.0"?>
<config>
<string name="ThemeSet"
value="recalbox" />
<string name="UpdateVersionFile" value="/recalbox/share/system/upgrade/recalbox.version.update" />
<string name="VersionFile" value="/recalbox/recalbox.version" />
</config>
avec la transformation XSLT ça continue à fonctionner !
$ xsltproc file.xsl file.xml
<?xml version="1.0"?>
<config>
<string name="ThemeSet" value="recalbox_custom"/>
<string name="UpdateVersionFile" value="/recalbox/share/system/upgrade/recalbox.version.update"/>
<string name="VersionFile" value="/recalbox/recalbox.version"/>
</config>
De même on aurait pu rajouter une espace par exemple : value= "recalbox", ou même value = "recalbox"
... et sed échouerait, à moins de le compliquer à plaisir pour traiter tous les possibles de XML (et ils sont très nombreux, comme rajouter des commentaires par exemples, etc...)
Tandis que la version XSLT est imperturbable, tant que le XML en entrée est valide et que le nom des nœuds que l'on cherche ne change pas, ça continue à fonctionner par vents et marées.
Pour le "long terme", c'est sans doute moins de soucis de maintenance.
Donc, tu connais l'histoire du marteau : "quand on a un marteau, tous les problèmes ressemblent à un clou !". Eh bien là précisément, tu as une vis. Alors oui tu peux toujours l'enfoncer avec le marteau, mais prendre un tournevis est quand même plus adapté, propre et durable.
A toi de voir !
Dernière modification par Zakhar (Le 19/11/2017, à 13:18)
"A computer is like air conditioning: it becomes useless when you open windows." (Linus Torvald)
Hors ligne
#13 Le 19/11/2017, à 14:07
- ShellNoob
Re : [Résolu] SED / AWK pour récupérer variable dans fichier de conf XML
Oui, ton exemple est concret et y a pas photo si on veut être paré pour des montées de version de la distrib qui changerait la syntaxe du fichier XML.
En tout cas c'est bien grâce à vos réponses, j'arrives à parfaire mes compétences
Hors ligne