Forum Programmation.shell suppression de plusieurs lignes dans un texte

Posté par  .
Étiquettes : aucune
0
22
nov.
2005
Bonjour ,


Dans le cadre d'un developpement CGI, j'ai besoin de supprimer un ensemble de lignes dans un fichier de configuration.
le problème est que je ne sais pas du tout combien de ligne je dois suprimer.

En gros , je dois supprimer un bloc de ligne commençant par
'<tartanpion "montruc">'
et finissant par :
''
(c'est pas exactement une syntaxe html , mais ça y ressemble beaucoup ;-) )

le problème c'est que ce bloc se répète plusieurs fois dans le fichier , il m'est donc impossible de supposer qu'il faut tout supprimer jusqu'à n'importe kel balise de type ' , il faut obligatoirement que je supprime jusqu'à la balise fermante la plus proche.

J'ai pas vraiment d'idée sur la commande à utiliser.
j'avais pensé passer par un sed avec le paramètre d, mais d'après ce que j'ai compris ça ne peut fonctioner que si je connais le texte de chaque ligne (ce qui n'est pas le cas).

Je suppose qu'un awk pourrait faire ce genre de truc , malheuresement j'ai du mal à comprendre le fonctionnement de cette commande. (en particulier pour préciser que awk doit rechercher la chaine '', la plus proche)

est-ce que quelqu'un aurait une idée ??

Merci d'avance.
  • # si je me souviens bien

    Posté par  . Évalué à 1.

    awk fonctionne en ligne par ligne
    donc si tu n'as pas plusieurs balyse sur une même ligne le problème est réglé
    sinon tu peux regarder du coté des expressions régulieres, le not ( ! ou ^ ) peuvent etre tres utiles.

    n'ayant pas la balise de fin sous les yeux j'ai du mal a voir ce qui peut poser un problème :P

    voila.

    ps: pour ces cas d'école, les recherche sur les expressions régulieres ne font pas de mal.

    Il ne faut pas décorner les boeufs avant d'avoir semé le vent

    • [^] # Re: si je me souviens bien

      Posté par  . Évalué à 1.

      Merci beaucoup pour la réponse , mais je crois que je me suis mal exprimé : je recommence ;-) ...

      le bloc à supprimer est de la forme


      balise mavariable
      lignes de texte
      lignes de texte
      lignes de texte
      finbalise


      donc il est impossible d'évaluer chaque ligne une par une pour vérifier si elle ne contient pas la balise en question.
      A mon avis il faut plutot faire une boucle while : Tant que on ne tombe pas sur '' , alors supprimer les lignes. (enfin un truc dans ce genre la) .

      La difficulté vient du fait qu'il faut commencer le While uniquement à partir de la première balise.
      (vu qu'il peut y avoir plusieurs ouvertures/fermetures de balise, ça risque de ne pas fonctioner si je ne précise pas qu'il faut commencer la vérification à partir d'une ligne précise....)

      Par conséquent je pense qu'il est impossible d'utiliser des expressiosn régulières pour résoudre le problème (mais je peux me tromper).

      Le problème reste donc posé....
      • [^] # Re: si je me souviens bien

        Posté par  . Évalué à 1.

        avec awk ca se fait facile :P

        astuce : sert toi d'une variable pour indiquer s'il faut afficher ^^
        quand tu tombe sur la balise, tu met la variable a faux
        quand tu tombe sur la fin de balise, tu met la variable a vrai :)

        si la variable est a vrai tu affiches

        exercice suivant: permettre l'imbrication des balises ^^ :P

        Il ne faut pas décorner les boeufs avant d'avoir semé le vent

        • [^] # Re: si je me souviens bien

          Posté par  . Évalué à 1.

          o_o

          J'avais pas du tout envisager le problème dans ce sens la ...^o^

          Merci beaucoup , il me reste plus qu'à étudier comment faire ça avec un awk. ;-)

          PS : l'exercice suivant est alléchant mais pas forcément utile dans mon cas ;-) j'y réfléchirais à l'occaz
  • # Pourquoi pas avec Perl ?

    Posté par  . Évalué à 0.

    et finissant par :

    ''

    Je suppose que tu voulais dire '</tartanpion>', mais que c'est parti en postant, non ?

    Je te suggérerais une solution avec Perl :
    perl -0777 -pe 's!<tartanpion(\s.*?)?>.*?</tartanpion>!!sg' fichier
    voire, si tu veux supprimer les éventuelles lignes vides qui pourraient rester après avoir retiré tes balises :
    perl -0777 -pe 's!<tartanpion(\s.*?)?>.*?</tartanpion>!!sg; s!\n\s*\n!\n!g' fichier

    Même si ton problème ressemble à du boulot typique AWK, Perl a quelques petits trucs qui simplifient l'opération :
    - -0777 fixe la fin de ligne au caractère de code octal 777, inexistant, donc permet de tout traiter comme une seule ligne; ainsi une seule expression régulière peut attrapper ta balise d'ouverture et celle de fermeture, même si elles sont sur plusieurs lignes (avec l'option s de la subsittution);
    - *?, comme *, correspond à 0 à n fois le caractère précedent, sauf qu'il prend en priorité la chaîne la plus petite et non pas la plus grande (sinon, l'expression globale zapperait de ta première balise ouvrante à la dernière fermante);
    - avec la substitution s/// comme avec les autres opérations utilisant les expressions régulières, on peut utiliser d'autres caractères que / comme séparation, ça peut rendre l'écriture plus agréable si la chaîne qu'on recherche ou celle de remplacement contient des /.
    - l'option -i peut te permettre de modifier le fichier directement en place :
    perl -0777 -pi -e 's!<tartanpion(\s.*?)?>.*?</tartanpion>!!sg' fichier
    éventuellement en sauvegardant l'ancienne version :
    perl -0777 -pi.bak -e 's!<tartanpion(\s.*?)?>.*?</tartanpion>!!sg' fichier

    « Le fascisme c’est la gangrène, à Santiago comme à Paris. » — Renaud, Hexagone

    • [^] # Re: Pourquoi pas avec Perl ?

      Posté par  . Évalué à 2.

      Juste une précision : l'intérêt est de supporter une balise en milieu de ligne, voire plusieurs sur une ligne.
      Si tes balises sont toujours toutes seules sur une ligne, la version de bigben99 suffit.

      « Le fascisme c’est la gangrène, à Santiago comme à Paris. » — Renaud, Hexagone

  • # sed

    Posté par  . Évalué à 1.

    Tu peux faire sed -e "s/<pattern_debut>/,/<pattern_fin>/d"
    Exemple:
    bruno@silver:/tmp$ cat toto.txt
    AA
    BB
    CC
    DD
    EE
    FF
    bruno@silver:/tmp$ sed -e "/BB/,/DD/d" toto.txt
    AA
    EE
    FF
    bruno@silver:/tmp$

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.