Contenu | Rechercher | Menus

Annonce

Toute l'équipe d'ubuntu-fr vous souhaite un joyeux Noël et une bonne et heureuse année 2018.

Ubuntu 16.04 LTS
Commandez vos DVD et clés USB Ubuntu-fr !

Pour en savoir un peu plus sur l'équipe du forum.

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

#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

ShellNoob #5 a écrit :

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. big_smile

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. big_smile

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 smile

Hors ligne