[RESOLU] [SHELL] extraction et reformattage des données d'un fichier

extraction et reformattage des données d'un fichier [RESOLU] [SHELL] - Shell/Batch - Programmation

Marsh Posté le 08-06-2010 à 16:03:00    

Bonjour à tous,
 
Je rencontre des difficultés pour extraire des données d'un fichier *.xml et les reformatter dans un nouveau fichier *.txt. Après quelques tentatives avec sed je n'ai pas réussi. Je viens donc solliciter votre aide.
 
Un exemple visuel vaut mieux qu'un grand discours...
 
Mon fichier *.xml contient plusieurs balises pour chaque élément :

Citation :

   <attribute name="ELEMENT-00" description="desc">
        <field name="section" value="1. The first section"/>
        <field name="title" value="First Element"/>
        <field name="help" value="&lt;p&gt;Set Element String ($Element00String)"/>
    <attribute name="ELEMENT-01" description="desc">
        <field name="section" value="1. The first section"/>
        <field name="title" value="Second Element"/>
        <field name="help" value="&lt;p&gt;Set Element String ($Element01String)"/>
    <attribute name="OPTION-00" description="desc">
        <field name="section" value="2. The second section"/>
        <field name="title" value="First Option"/>
        <field name="help" value="&lt;p&gt;Set Option String ($Option00String)"/>

Chaque élément est formatté de la même façon, mais certains peuvent avoir des balises "field name" supplémentaires.
 
 
Mon but est de constituer un fichier de paramètres à partir des données présentes dans le fichier *.xml, tel que :

Citation :


##1. The first section
#First Element - Set Element String ($Element00String)
ELEMENT-00=""
#Second Element - Set Element String ($Element01String)
ELEMENT-01=""
 
##2. The second section
#First Option - Set Option String ($Option00String)
OPTION-00=""

Chaque élément contient une balise "section" qu'il me faudra limiter à une unique extraction. Dans le pire des cas, je pourrai toujours supprimer les doublons dans le fichier de sortie. Mon problème concerne essentiellement le "réordonancement" des données : remonter, descendre ou inverser des lignes.
 
J'ai essayé plusieurs choses avec sed sans résultat. Etant débutant en scripts, je ne sais pas quel langage est le mieux adapté. D'après ce que j'ai trouvé sur la toile, il semble que perl soit bien adapté à ce type de travail. Je n'ai pas de préférence entre sed, awk ou perl car je n'ai pas de contraintes particulières sur le système.
 
Je vous remercie par avance pour l'aide que vous allez m'apporter.
 
 
Cordialement,
 
algp


Message édité par algp le 09-06-2010 à 17:29:26
Reply

Marsh Posté le 08-06-2010 à 16:03:00   

Reply

Marsh Posté le 09-06-2010 à 13:49:20    

Voici un script awk qui devrait convenir

Code :
  1. awk -F '"' '
  2. $1 ~ /<attribute/ {
  3.    element = $2;
  4.    next;
  5. }
  6. $1 !~ /<field name/ { next }
  7. $2 == "section" {
  8.    sectionValue = $4
  9.    if (sectionValue in listeSections) {
  10.       sectionId = listeSections[$4];
  11.    } else {
  12.       nbSections++;
  13.       sectionId = nbSections;
  14.       listeSections[sectionValue] = sectionId;
  15.       section[sectionId, "value"    ] = $4;
  16.       section[sectionId, "nbElement"] = 0;
  17.    }
  18.    nbElement = ++section[sectionId, "nbElement"];
  19.    section[sectionId, "element", nbElement] = element;
  20.    next;
  21. }
  22. $2 == "title" {
  23.    section[sectionId, "title", nbElement] = $4;
  24.    next;
  25. }
  26. $2 == "help" {
  27.    sub(/^[^;]*;[^;]*;/, "", $4);
  28.    section[sectionId, "help", nbElement] = $4;
  29.    next;
  30. }
  31. END {
  32.    for (s=1; s<=nbSections; s++) {
  33.       printf "\n##%s\n", section[s, "value"];
  34.       for (e=1; e<=section[s, "nbElement"]; e++) {
  35.          printf "#%s - %s\n", section[s, "title", e], section[s, "help", e];
  36.          printf "%s=\"\"\n", section[s, "element", e];
  37.       }
  38.    }
  39. }
  40. ' fichier.xml


Le champ "section" doit obligatoirement être placé avant les champs "title" et "help".
Pour le fichier xml suivant :

   <attribute name="ELEMENT-00" description="desc">
        <field name="section" value="1. The first section"/>
        <field name="title" value="First Element"/>
        <field name="help" value="&lt;p&gt;Set Element String ($Element00String)"/>
    <attribute name="ELEMENT-01" description="desc">
        <field name="section" value="1. The first section"/>
        <field name="title" value="Second Element"/>
        <field name="help" value="&lt;p&gt;Set Element String ($Element01String)"/>
    <attribute name="OPTION-00" description="desc">
        <field name="section" value="2. The second section"/>
        <field name="title" value="First Option"/>
        <field name="help" value="&lt;p&gt;Set Option String ($Option00String)"/>
    <attribute name="ELEMENT-02" description="desc">
        <field name="section" value="1. The first section"/>
        <field name="title" value="Third Element"/>
        <field name="help" value="&lt;p&gt;Set Element String ($Element02String)"/>
    <attribute name="PARAM-01" description="desc">
        <field name="section" value="3. The param section"/>
        <field name="title" value="First parameter"/>
        <field name="help" value="&lt;p&gt;Set Param String ($Param00String)"/>
    <attribute name="OPTION-01" description="desc">
        <field name="section" value="2. The second section"/>
        <field name="title" value="Second Option"/>
        <field name="help" value="&lt;p&gt;Set Option String ($Option01String)"/>

le résultat est :

##1. The first section
#First Element - Set Element String ($Element00String)
ELEMENT-00=""
#Second Element - Set Element String ($Element01String)
ELEMENT-01=""
#Third Element - Set Element String ($Element02String)
ELEMENT-02=""
 
##2. The second section
#First Option - Set Option String ($Option00String)
OPTION-00=""
#Second Option - Set Option String ($Option01String)
OPTION-01=""
 
##3. The param section
#First parameter - Set Param String ($Param00String)
PARAM-01=""


 
 
Jean-Pierre.

Reply

Marsh Posté le 09-06-2010 à 17:28:06    

Merci beaucoup Jean-Pierre, ça marche parfaitement. AWK est vraiment un outil puissant...
 
Je suis agréablement surpris, je m'atendais à obtenir des pistes avec des extraits de code qui me permettrai de trouver la solution et je me retrouve avec un script clé en main.
 
 
Dans l'ensemble j'ai compris le fonctionnement du script et lui ai donc ajouté quelques lignes pour l'adapter totalement à l'environnement final.
 
Juste une petite question, pourquoi ne pas mettre directement

Citation :

.*;

dans la regex de substitution de la ligne 32 ?

Citation :

sub(/^[^;]*;[^;]*;/, "", $4);


[quote]sub(/^.*;/, "", $4);[quote]
J'ai essayé et ça fonctionne, néanmoins je ne sais pas comment le script sait sur quel point-virgule s'arrêter.  
 
Encore merci pour ton aide précieuse :)  

Reply

Marsh Posté le 09-06-2010 à 18:45:48    

Si tu utilises le pattern

Citation :

^.;

la substitution s'effectue jusqu'au dernier caractère ';' ce qui peut ne pas convenir s'il y a plus de 2 ';'.
 
Avec le pattern que j'ai utilisé

Citation :

^[^;]*;[^;]*;

la substitution s'arrête au second ';' (s'il n'y a qu'un seul ';' il n'y a pas de substitution).
 
 
Jean-Pierre.

Reply

Marsh Posté le 10-06-2010 à 10:23:19    

Merci Jean-Pierre.
 
Je vais donc conserver ton pattern car le champ help est susceptible de contenir des point-virgules dans son contenu.
 
 
algp

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed