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 :

Réécriture des fichiers


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Mai 2007
    Messages
    34
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 34
    Par défaut Réécriture des fichiers
    Bonjour,

    J'ai un fichier de conf qui contient des balises de ce genre:
    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
     
     
    <Location /toto/ >
            ProxyPass        http://m.toto.com/ retry=0
            ProxyPassReverse http://m.toto.com/
            ProxyPassReverseCookiePath / /toto/
            ProxyPassReverseCookieDomain .toto.com 
     
            SetOutputFilter INFLATE;proxy-html;DEFLATE
            ProxyHTMLLogVerbose On
            ProxyHTMLExtended On
            ProxyHTMLURLMap  / /toto/
            ProxyHTMLURLMap  href="m.toto.com/" href="/toto/"
            ProxyHTMLURLMap  http://m.toto.com/ /toto/
            ProxyHTMLURLMap m.toto.com 
    </Location>
     
    <Location /titi/ >
            ProxyPass        http://m.titi.com/ retry=0
            ProxyPassReverse http://m.titi.com/
            ProxyPassReverseCookiePath / /titi/
     </Location>
    Je dois transformer ce fichier comme suit:

    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
     
     
            ProxyPass        /toto/ http://m.toto.com/ retry=0
            ProxyPassReverse /toto/ http://m.toto.com/
    <Location /toto/ >
            ProxyPassReverseCookiePath / /toto/
            ProxyPassReverseCookieDomain .toto.com 
     
            SetOutputFilter INFLATE;proxy-html;DEFLATE
            ProxyHTMLLogVerbose On
            ProxyHTMLExtended On
            ProxyHTMLURLMap  / /toto/
            ProxyHTMLURLMap  href="m.toto.com/" href="/toto/"
            ProxyHTMLURLMap  http://m.toto.com/ /toto/
            ProxyHTMLURLMap m.toto.com 
    </Location>
     
            ProxyPass        /titi/ http://m.titi.com/ retry=0
            ProxyPassReverse /titi/ http://m.titi.com/
    <Location /titi/ >
            ProxyPass        http://m.titi.com/ retry=0
            ProxyPassReverse http://m.titi.com/
            ProxyPassReverseCookiePath / /titi/
     </Location>
    C'est à dire jour chaque jonction comme /toto et /titi/, il faut sortir les balises
    ProxyPass et ProxyPassReverse.

    J'ai mis en place un script mais qui permet de un fichier qui contient un fichier qui contient une seule jonction de type toto:
    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
     
    #!/bin/sh
    TMPFILE1="/tmp/temp1.txt"
    TMPFILE2="/tmp/temp2.txt"
     
    while read curline; do
        grep -e "ProxyPass " -e "ProxyPassReverse "|sed 's/http/\/toto\/ http/g' > $TMPFILE1
    done < input.txt
     
    echo "<Location /toto/ >" > $TMPFILE2
     
    while read curline; do
        grep -v -e "ProxyPass " -e "ProxyPassReverse " >> $TMPFILE2
    done < input.txt
     
    cat $TMPFILE1 > output.txt
    cat $TMPFILE2 >> output.txt
     
    rm -f $TMPFILE1 $TMPFILE2
    Alors comment je peux modifier mon script pour traiter un fichier d'entrée qui contient plusieurs jonction.

    Merci d'avance.

  2. #2
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 658
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 658
    Par défaut
    Bonjour,

    comment je peux modifier mon script pour traiter un fichier d'entrée qui contient plusieurs jonction.
    tu peux réécrire ton script, pour qu'il sache lire un fichier, et quand une ligne correspond au motif "<Location.*", il la conserve dans une variable jusqu'à ce qu'une ligne corresponde à "ProxyPassReverse", et alors à ce moment, il écrira la ligne courante (ProxyPassReverse) et la ligne conservée.
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Membre averti
    Inscrit en
    Mai 2007
    Messages
    34
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 34
    Par défaut
    est ce que vous pouvez me détailler un peu plus comment faire.

  4. #4
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 102
    Par défaut
    Si le fichier suit le formatage que tu décris, ça se fait assez facilement en awk avec un automate à 2 états "à l'intérieur de la balise Location"/"à l'extérieur de la balise Location":
    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
    32
    33
    Begin:
    - On démarre avec état := "extérieur"
     
    Quand on rencontre une balise ouvrante,
    - on stocke le nom associé à la balise (par exemple /toto/)
    - on passe à état := "intérieur"
    - on initialise le num-ligne := 0
    - on stocke la ligne courante (à la position num-ligne++)
    - next
     
    Quand on rencontre une balise fermante,
    - on stocke la ligne courante (à la position num-ligne++)
    - on affiche le ProxyPass modifié, le ProxyPassReverse modifié et toutes les lignes stockées dans le tableau
    - on passe à état := "extérieur"
    - next
     
    Quand on rencontre ProxyPass,
    - on vérifie que état == "intérieur"
    - on le stocke dans ProxyPass
    - next
     
    Quand on rencontre ProxyPassReverse,
    - on vérifie que état == "intérieur"
    - on le stocke dans ProxyPassReverse
    - next
     
    Pour toute ligne,
    - si état == "extérieur"
       alors afficher la ligne telle quelle
       sinon on stocke la ligne courante (à la position num-ligne++)
     
    End:
    - on vérifie que état == "extérieur"

  5. #5
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Par défaut
    Salut,

    Juste un truc... dans ton 1er exemple "toto", tu sors tes deux lignes des balises, mais dans ton 2nd exemple "titi", tu les sors mais tu les conserves également

    Lequel est le bon ?

  6. #6
    Membre averti
    Inscrit en
    Mai 2007
    Messages
    34
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 34
    Par défaut
    L'exemple de Toto est le bon.
    Je n'arrive pas à le généraliser à tout mon fichier.

  7. #7
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Par défaut
    Les enregistrements sont toujours dans le même ordre ? À savoir :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <Location /blabla/>
    ProxyPass        blabla retry=0
    ProxyPassReverse blabla

  8. #8
    Membre averti
    Inscrit en
    Mai 2007
    Messages
    34
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 34
    Par défaut
    oui c'est toujours le même ordre

  9. #9
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 102
    Par défaut
    Citation Envoyé par jack-ft Voir le message
    Si le fichier suit le formatage que tu décris, ça se fait assez facilement en awk avec un automate à 2 états "à l'intérieur de la balise Location"/"à l'extérieur de la balise Location":
    Plus précisément, avec 17 lignes de awk (pas très tassées!):

    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    #!/bin/awk
    # Time-stamp: <2013/01/22 10:40:33 jack-ft>
     
    # <Location /toto/ >
    #         ProxyPass        http://m.toto.com/ retry=0
    #         ProxyPassReverse http://m.toto.com/
    #         ProxyPassReverseCookiePath / /toto/
    #         ProxyPassReverseCookieDomain .toto.com 
    #         SetOutputFilter INFLATE;proxy-html;DEFLATE
    #         ProxyHTMLLogVerbose On
    #         ProxyHTMLExtended On
    #         ProxyHTMLURLMap  / /toto/
    #         ProxyHTMLURLMap  href="m.toto.com/" href="/toto/"
    #         ProxyHTMLURLMap  http://m.toto.com/ /toto/
    #         ProxyHTMLURLMap m.toto.com 
    # </Location>
     
    # <Location /titi/ >
    #         ProxyPass        http://m.titi.com/ retry=0
    #         ProxyPassReverse http://m.titi.com/
    #         ProxyPassReverseCookiePath / /titi/
    #  </Location>
     
    # =>
     
    #         ProxyPass        /toto/ http://m.toto.com/ retry=0
    #         ProxyPassReverse /toto/ http://m.toto.com/
    # <Location /toto/ >
    #         ProxyPassReverseCookiePath / /toto/
    #         ProxyPassReverseCookieDomain .toto.com 
     
    #         SetOutputFilter INFLATE;proxy-html;DEFLATE
    #         ProxyHTMLLogVerbose On
    #         ProxyHTMLExtended On
    #         ProxyHTMLURLMap  / /toto/
    #         ProxyHTMLURLMap  href="m.toto.com/" href="/toto/"
    #         ProxyHTMLURLMap  http://m.toto.com/ /toto/
    #         ProxyHTMLURLMap m.toto.com 
    # </Location>
     
    #         ProxyPass        /titi/ http://m.titi.com/ retry=0
    #         ProxyPassReverse /titi/ http://m.titi.com/
    # <Location /titi/ >
    #         ProxyPassReverseCookiePath / /titi/
    #  </Location>
     
    # Begin:
    # - On démarre avec état := "extérieur"
     
    # Quand on rencontre une balise ouvrante,
    # - on stocke le nom associé à la balise (par exemple /toto/)
    # - on passe à état := "intérieur"
    # - on initialise le num-ligne := 0
    # - on stocke la ligne courante (à la position num-ligne++)
    # - next
     
    # Quand on rencontre une balise fermante,
    # - on stocke la ligne courante (à la position num-ligne++)
    # - on affiche le ProxyPass modifié, le ProxyPassReverse modifié et toutes les lignes stockées dans le tableau
    # - on passe à état := "extérieur"
    # - next
     
    # Quand on rencontre ProxyPass,
    # - on vérifie que état == "intérieur"
    # - on le stocke dans ProxyPass
    # - next
     
    # Quand on rencontre ProxyPassReverse,
    # - on vérifie que état == "intérieur"
    # - on le stocke dans ProxyPassReverse
    # - next
     
    # Pour toute ligne,
    # - si état == "extérieur"
    #    alors afficher la ligne telle quelle
    #    sinon on stocke la ligne courante (à la position num-ligne++)
     
    # End:
    # - on vérifie que état == "extérieur"
     
    BEGIN { state = "out" }
     
    /<Location/ {
        state = "in";
        name = $2;
        nl = 0;
        Lines[++nl] = $0;
        next;
    }
     
    /Location>/ {
        Lines[++nl] = $0;
        gsub("http", name " http", PP);
        gsub("http", name " http", PPR);
        print(PP);
        print(PPR);
        for(n=1; n<=nl; n++) { print Lines[n] ; };
        state = "out";
        next;
    }
     
    {
        if (state == "out") { print $0; next; }
        else if ($1 == "ProxyPass")        { PP  = $0; next; }
        else if ($1 == "ProxyPassReverse") { PPR = $0; next; }
        else { Lines[++nl] = $0; }
    }
    et l'appel est awk -f file.awk conf_file où file.awk est le nom du fichier précédent.

    PS: ça me paraît plus facile à lire et adapter, donc plus souple que du sed

  10. #10
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 658
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 658
    Par défaut

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    while IFS='' read line
    do
       case $line in
          \<Location*) tmp="$line"
          ;;
          *ProxyPassReverse\ *) echo "$line"
             echo "$tmp"
          ;;
          *) echo "$line"
       esac
    done < fichier
    pour faire ça correctement il faudrait utiliser XSLT, avec des programmes comme xsltproc, ou xmlstarlet
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  11. #11
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Par défaut
    Salut,
    Citation Envoyé par N_BaH Voir le message

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    while IFS='' read line
    do
       case $line in
          \<Location*) tmp="$line"
          ;;
          *ProxyPassReverse\ *) echo "$line"
             echo "$tmp"
          ;;
          *) echo "$line"
       esac
    done < fichier
    Euh... c'est pas que je veuille médire, mais il manque un ch'tit truc dans la mise en forme de ton code

    La sortie devant ressembler à ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
            ProxyPass        /toto/ http://m.toto.com/ retry=0
            ProxyPassReverse /toto/ http://m.toto.com/

  12. #12
    Membre averti
    Inscrit en
    Mai 2007
    Messages
    34
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 34
    Par défaut
    Citation Envoyé par N_BaH Voir le message

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    while IFS='' read line
    do
       case $line in
          \<Location*) tmp="$line"
          ;;
          *ProxyPassReverse\ *) echo "$line"
             echo "$tmp"
          ;;
          *) echo "$line"
       esac
    done < fichier
    pour faire ça correctement il faudrait utiliser XSLT, avec des programmes comme xsltproc, ou xmlstarlet

    Bonjour,

    Si je veux faire ce traitement sous Windows, j'ai la structure suivante:
    dossier1
    -->fichier
    dossier2
    -->fichier

    ....

    donc pour tout fichier d'un dossier, je veux appliquer le traitement de réécriture.
    est ce que je dois installer un outil de traitement xml?

    Merci

  13. #13
    Membre averti
    Inscrit en
    Mai 2007
    Messages
    34
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 34
    Par défaut
    Merci beaucoup jack-ft.
    Ton code fonctionne bien.

    Merci à tous pour votre aide

  14. #14
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 658
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 658
    Par défaut
    Citation Envoyé par zipe31
    il manque un ch'tit truc dans la mise en forme de ton code
    pff, trois fois rien :
    Code BASH : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #!/bin/bash
     
    while IFS='' read line
    do
       case $line in
          \<Location*) tmp="$line"
             [[ $tmp =~ (/[^/]*/) ]] && loc="${BASH_REMATCH[1]}"
          ;;  
          *ProxyPass\ *) echo "${line/http/$loc http}"
          ;;  
          *ProxyPassReverse\ *) printf '%s\n' "${line/http/$loc http}" "$tmp"
          ;;  
          *) echo "$line"
       esac
    done <fichier
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  15. #15
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    pff, trois fois rien :
    C'est souvent les petits riens qui font toute la différence

    Merci

  16. #16
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 102
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    pff, trois fois rien :
    Code BASH : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #!/bin/bash
     
    while IFS='' read line
    do
       case $line in
          \<Location*) tmp="$line"
             [[ $tmp =~ (/[^/]*/) ]] && loc="${BASH_REMATCH[1]}"
          ;;  
          *ProxyPass\ *) echo "${line/http/$loc http}"
          ;;  
          *ProxyPassReverse\ *) printf '%s\n' "${line/http/$loc http}" "$tmp"
          ;;  
          *) echo "$line"
       esac
    done <fichier
    Ne marche que si les 3 lignes "<Location", "ProxyPass" et "ProxyPassReverse" sont contiguës et dans cet ordre...

Discussions similaires

  1. Réécriture des fichiers
    Par ensienne dans le forum VBScript
    Réponses: 1
    Dernier message: 09/07/2013, 14h26
  2. Importer des fichiers textes délimités
    Par Invité dans le forum Outils
    Réponses: 2
    Dernier message: 23/09/2002, 13h56
  3. Réponses: 3
    Dernier message: 25/07/2002, 10h42
  4. [langage] comment créer des fichiers ?
    Par Anonymous dans le forum Langage
    Réponses: 3
    Dernier message: 05/05/2002, 16h33
  5. Comparer des fichiers de données : Quel Langage ?
    Par Anonymous dans le forum Langages de programmation
    Réponses: 6
    Dernier message: 24/04/2002, 22h37

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