IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Shell et commandes GNU Discussion :

Insérer un fichier entre des motifs


Sujet :

Shell et commandes GNU

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2017
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2017
    Messages : 10
    Points : 10
    Points
    10
    Par défaut Insérer un fichier entre des motifs
    (re)Bonjour,

    je sais que c'est pas top d'attaquer du XML avec sed mais je le fais sur un distrib ou il n'y a pas le package xmlstarlet et pas possibilité de l'installer.

    Toujours dans l'optique de manipuler du XML.
    Mon fichier principal es_systems.xml à cette forme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    <?xml version="1.0"?>
    <systemList>
    <system>
        <fullname></fullname>
        <name></name>
        <path></path>
        <extension></extension>
        <command> </command>
        <platform></platform>
        <theme></theme>
        <emulators>
          <emulator name="">
            <cores>
              <core></core>
            </cores>
          </emulator>
        </emulators>
      </system>
     
    </systemList>
    Je souhaiterais insérer dans ce fichier existant le contenu d'un fichier jeux.xml (ayant la même forme que ce qui se trouve entre les balises </system> mais au bon endroit entre les balises
    <systemList>
    </systemList>

    du fichier principal.

    Quelle serait la bonne façon de faire?

  2. #2
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 563
    Points : 460
    Points
    460
    Par défaut
    Salut, perso je ferai ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    IFS=''
    while read ligne
    do
     echo "${ligne}"
     [[ "${ligne}" == "<systemList>" ]] && cat jeux.xml
    done < es_systems.xml
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    IFS=''
    while read ligne
    do
     [[ "${ligne}" == "</systemList>" ]] && cat jeux.xml
     echo "${ligne}"
    done < es_systems.xml
    On peut remplacer == par =~ si jamais il risque d'y avoir des espaces avant ou après le <systemList> mais ça alourdit.
    Sous Kubuntu 20.04

  3. #3
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    salut,

    en complément une solution en awk, sur le même principe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk -vfile=jeux.xml 'BEGIN{oldRS=RS;RS="^$";getline data<file;RS=oldRS}/<\/system>/{$0=$0"\n"data}{print}' es_systems.xml

  4. #4
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2017
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2017
    Messages : 10
    Points : 10
    Points
    10
    Par défaut
    Merci à tous les deux pour vos propositions

    hizoka, j'ai ajouté un redirection à la fin si non cela montre le résultat attendu à l'écran sans modifier le fichier original.
    Donc, je rediriges dans un fichier: es_systems_modifie.xml

    Citation Envoyé par hizoka Voir le message
    Salut, perso je ferai ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    IFS=''
    while read ligne
    do
     echo "${ligne}"
     [[ "${ligne}" == "<systemList>" ]] && cat jeux.xml
    done < es_systems.xml >> es_systems_modifie.xml
    ça marche bien en ajoutant un seul jeux.xml

    Mais si je rejoue le script avec un deuxième fichier, ex jeux_2.xml pour qu'il intégère aussi es_systems.xml, le problème c'est que ça me duplique les balises, j'ai deux fois les balises ouvrantes / fermante principale <systemList></systemList>

    ---

    BufferBob, j'ai également essayé ta proposition à base de AWK mais ça me place le contenu importé depuis le fichier jeux.xml à la suite des balises et non entre.

    <systemList>

    </systemList>

  5. #5
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    Citation Envoyé par ShellNoob Voir le message
    BufferBob, j'ai également essayé ta proposition à base de AWK mais ça me place le contenu importé depuis le fichier jeux.xml à la suite des balises et non entre.
    au temps pour moi j'avais mal compris l'énoncé, il suffit de remplacer /<\/systemList>/ par /<systemList>/ tout simplement.

    hum.. bon si on considère le fichier es_systems.xml correctement indenté :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <?xml version="1.0"?>
    <systemList>
       <system>
          <fullname></fullname>
          <name></name>
          <path></path>
          <extension></extension>
          <command> </command>
          <platform></platform>
          <theme></theme>
          <emulators>
             <emulator name="">
                <cores>
                   <core></core>
                </cores>
             </emulator>
          </emulators>
       </system>
    </systemList>
    et le fichier jeux.xml bidon, indenté pour l'occasion :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
       <machin>
          TOTO
          POUET
          COINCOIN
       </machin>
    la commande renvoie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    <?xml version="1.0"?>
    <systemList>
       <system>
          <fullname></fullname>
          <name></name>
          <path></path>
          <extension></extension>
          <command> </command>
          <platform></platform>
          <theme></theme>
          <emulators>
             <emulator name="">
                <cores>
                   <core></core>
                </cores>
             </emulator>
          </emulators>
       </system>
       <machin>
          TOTO
          POUET
          COINCOIN
       </machin>
    
    </systemList>
    avec tout en bas un retour chariot parasite avant la balise </systemList>, c'est pas ça le but ?
    c'est entre quelles balises qu'il faut insérer le chose ?

  6. #6
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2017
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2017
    Messages : 10
    Points : 10
    Points
    10
    Par défaut
    Citation Envoyé par BufferBob Voir le message
    au temps pour moi j'avais mal compris l'énoncé, il suffit de remplacer /<\/systemList>/ par /<systemList>/ tout simplement.
    Exact ça fonctionne bien ton AWK sans le /

    Du coup ça donne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk -vfile=jeux.xml 'BEGIN{oldRS=RS;RS="^$";getline data<file;RS=oldRS}/<systemList>/{$0=$0"\n"data}{print}' es_systems.xml >> es_systems_modifie.xml
    es_systems.xml -> lu mais non modifié
    es_systems_modifie.xml -> le même avec le contenu du fichier jeux.xml importé de dans

    problème si je relance une deuxième fois la commande mais en remplaçant jeux.xml par jeux_2.xml pour insérer un autre ensemble, cela duplique les balises <systemList></systemList> du fait de le redirection dans le fichier

  7. #7
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    Citation Envoyé par ShellNoob Voir le message
    problème si je relance une deuxième fois la commande mais en remplaçant jeux.xml par jeux_2.xml pour insérer un autre ensemble, cela duplique les balises <systemList></systemList> du fait de le redirection dans le fichier
    j'ai aucun problème de ce type, je vois d'ailleurs pas trop comment ça pourrait arriver :
    Code script.awk : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    BEGIN {
       oldRS = RS; RS = "^$"
       getline data < file; RS = oldRS
    }
    /<systemList>/ {
       $0 = $0 "\n" substr(data, 1, length(data) - 1)   # pour éviter le retour chariot parasite, purement esthétique...
    }
    { print }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    $ awk -i inplace -vfile=jeux.xml   -f script.awk es_systems.xml
    $ awk -i inplace -vfile=jeux_2.xml -f script.awk es_systems.xml
    $ cat es_systems.xml
    <?xml version="1.0"?>
    <systemList>
       <truc>
          BIDULE
          BOUZIN
       </truc>
       <machin>
          TOTO
          POUET
          COINCOIN
       </machin>
       <system>
          <fullname></fullname>
          <name></name>
          <path></path>
          <extension></extension>
          <command> </command>
          <platform></platform>
          <theme></theme>
          <emulators>
             <emulator name="">
                <cores>
                   <core></core>
                </cores>
             </emulator>
          </emulators>
       </system>
    </systemList>

  8. #8
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2017
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2017
    Messages : 10
    Points : 10
    Points
    10
    Par défaut
    Merci pour ton aide et ta patience.
    J'ai créé le script script.awk

    Ensuite depuis le prompt je lance
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk -i inplace -vfile=jeux.xml   -f script.awk es_systems.xml


    mais visiblement le paramètre -i ne peut être interprété, BusyBox me retourne le message suivant

    Usage: awk [OPTIONS] [AWK_PROGRAM] [FILE]...

    -v VAR=VAL Set variable
    -F SEP Use SEP as field separator
    -f FILE Read program from FILE
    -e AWK_PROGRAM

  9. #9
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    Citation Envoyé par ShellNoob Voir le message
    visiblement le paramètre -i ne peut être interprété
    le flag ne fonctionne qu'avec GNU Awk (gawk), mais le principe reste le même :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    $ awk -vfile=jeux.xml   -f script.awk es_systems.xml > temp.xml && mv temp.xml es_systems.xml
    $ awk -vfile=jeux_2.xml -f script.awk es_systems.xml > temp.xml && mv temp.xml es_systems.xml
    $ head es_systems.xml
    <?xml version="1.0"?>
    <systemList>
       <truc>
          BIDULE
          BOUZIN
       </truc>
       <machin>
          TOTO
          POUET
          COINCOIN

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2010
    Messages
    345
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 345
    Points : 539
    Points
    539
    Par défaut
    Bonjour,
    Pour inserer aprés la balise <systemList>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed '/<systemList>/r jeux.xml' infile
    Pour inserer avant la balise </systemList>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed ':A;$bB;N;:B;/<\/systemList>/!b;h;s/.*/cat jeux.xml/e;G' infile
    Mais en voyant le dernier message, avec BusyBox, c'est pas gagné.
    Cordialement.

  11. #11
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    Citation Envoyé par ctac_ Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed '/<systemList>/r jeux.xml' infile
    propre.

  12. #12
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2017
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2017
    Messages : 10
    Points : 10
    Points
    10
    Par défaut
    Un énorme merci à vous deux! Les deux solutions proposées fonctionnent avec busybox

    Du coup ctac_ je retiens ta solution incroyablement simple et BufferBob, je prends ta méthode pour faire la redirection dans le fichier et faire l'écriture des paramètres retournées par le SED

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed '/<systemList>/r jeux.xml' es_systems.xml > temp.xml && mv temp.xml es_systems.xml

  13. #13
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 280
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 280
    Points : 12 729
    Points
    12 729
    Par défaut
    Pour éviter d'avoir un fichier temporaire, on peut passer par les redirection de fd (mais en cas de panne subite, on perd le fichier (tout comme un sed -i ) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    exec 3<es_systems.xml ; rm es_systems.xml ; sed '/<systemList>/r jeux.xml' <&3 >es_systems.xml; exec 3>&-
    Ici, on ouvre es_systems.xml sur le fd 3, puis on supprime le fichier (celui-ci ne sera plus disponible sauf pour le fd 3, ensuite on fait le sed dont on redirige le résultat directement dans le bon fichier, et le exec final sert à fermer le fd et donc à libérer la place de l'ancien fichier.

    Sinon, un petit détail: si jamais tu édites ton fichier dans un vrai éditeur xml, celui-ci pourrait supprimer les retour à la ligne car ceux-ci ne sont pas du tout obligatoires pour du xml, tu pourrais donc te retrouver avec un fichier d'une seule ligne qui serait tout à fait valide en xml mais par contre les solutions proposée pour le remplissage ne fonctionneraient plus...
    Cordialement.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 06/09/2016, 19h31
  2. Partage des fichiers entre projets Eclipse
    Par laura_cornel dans le forum Eclipse Java
    Réponses: 9
    Dernier message: 11/12/2006, 11h52
  3. Réponses: 3
    Dernier message: 17/11/2006, 18h12
  4. transfert d'information entre des fichiers
    Par Amallric dans le forum Langage
    Réponses: 10
    Dernier message: 21/09/2006, 08h50
  5. [win] problème pour partager des fichiers entre 2 pc
    Par goma771 dans le forum Administration
    Réponses: 1
    Dernier message: 01/12/2005, 16h15

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo