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

Linux Discussion :

Suppression de chaine (mais pas de ligne) sur plusieurs lignes


Sujet :

Linux

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Juillet 2004
    Messages : 17
    Points : 11
    Points
    11
    Par défaut Suppression de chaine (mais pas de ligne) sur plusieurs lignes
    Bonjour,
    je voudrais supprimer des portions de fichiers, entre deux balises, s'étalant sur plusieurs lignes.
    Mais cela ne correspond pas forcement à des lignes entières.
    Du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    blabla</truc><balise>
    nombre
    de
    lignes
    variable
    </balise><autre_truc>blabla
    et recupérer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    blabla</truc>
    <autre_truc>blabla
    Spontanément j'avais pensé à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    sed 's/<balise>.*<\/balise>//' fichier
    mais je viens de découvrir que le "." ne comprenait pas les fins de ligne.

    À votre avis est-ce possible avec sed ou faut il utiliser autre chose ?

    Merci

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 34
    Points : 41
    Points
    41
    Par défaut
    Salut

    Je te conseille plutôt d'utiliser perl :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    perl -0777 -pe 's/<balise>.*?<\/balise>//sg' fichier
    ici -0777 fait que le fichier sera considéré comme une ligne (avec -00, ça serait chaque paragraphe comme une ligne, ce qui est mieux si ça suffit)
    /g pour un remplacement global
    /s permet notamment que "." comprenne également les sauts de ligne. /m peut être utile aussi par exemple si on veut utiliser ^ ou $
    Comme pour (g)sed on peut ajouter l'option -i pour modifier sur place (y compris -i.bak)

    Concernant sed, tu pourras trouver ici trois exemples pour enlever tous les commentaires du type /* */ et ce qu'ils contiennent, y compris sur plusieurs lignes :
    http://sed.sourceforge.net/grabbag/s.../remccoms1.sed
    http://sed.sourceforge.net/grabbag/s...mccoms2.sh.txt
    http://sed.sourceforge.net/grabbag/s.../remccoms3.sed

    La première méthode est simple mais ne marche pas dans tous les cas, autrement dit elle ne marche pas.
    Les deux autres sont plus compliquées mais fonctionnent. La seconde est d'après mes tests deux fois plus rapide que la troisième, mais cette dernière tient compte d'un paramètre en plus.
    Mais les deux sont non seulement plus compliquées que perl, mais surtout bien plus lente

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Juillet 2004
    Messages : 17
    Points : 11
    Points
    11
    Par défaut
    Merci pour ta réponse, elle répond exactement à mes attente !

    Cela dit je n'avais pas cherché du coté de Perl car je n'en ais aucune connaissance et je n'aime pas trop les solutions copié-collé. Mais grâce à toi je n'ai plus le choix... Je vais me mettre à Perl.

    Du coup j'ai quelques petites questions sur ta solution :
    • Quel est l'intérêt de l'option -0777 si on utilise /s ?
    • Pourquoi ".*?" au lieu de ".*" ?

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 34
    Points : 41
    Points
    41
    Par défaut
    1)
    /s permet d'inclure le saut de ligne dans la classe des caractères correspondant à "."
    exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo -e "ab\ncd" | perl -pe 's/./#/g'
    donne :
    ##
    ##
    alors que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo -e "ab\ncd" | perl -pe 's/./#/sg'
    donne :
    #####

    Donc dans l'exemple de mon premier message, le /s est nécessaire, à moins par exemple de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    perl -0777pe 's/<balise>[\s\S]*?<\/balise>//g' fichier
    2) le point d'interrogation permet de rendre le quatificateur non gourmand.
    exemple : je veux supprimer tout ce qui est entre <debut> et <fin> ainsi que ceux-ci.
    si je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo  "<debut>a<fin>b<debut>c<fin>d" | perl -pe 's/<debut>.*<fin>//g'
    je vais obtenir "d" et non pas "bd" car ".*" ne se sera pas arrêté au premier <fin> mais au dernier (gourmand)

    Alors
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo  "<debut>a<fin>b<debut>c<fin>d" | perl -pe 's/<debut>.*?<fin>//g'
    J'obtiens bien "bd"


    Si tu veux faire la même chose avec sed, tu auras quelques difficultés car on ne peut pas rendre un quatificateur non gourmand.
    En revanche ssed ("super sed") supporte les regex PCRE via l'option -R et donc permet ceci.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Juillet 2004
    Messages : 17
    Points : 11
    Points
    11
    Par défaut
    Merci beaucoup pour ces explications
    J'avais pas entendu parler de ssed, ça peut être utile.

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

Discussions similaires

  1. Plusieurs lignes sur une ligne ?
    Par nikora dans le forum Shell et commandes GNU
    Réponses: 6
    Dernier message: 16/06/2015, 18h27
  2. [XL-2010] Copier/coller selon critère existant sur plusieurs lignes sur une même ligne
    Par Frs95 dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 18/12/2014, 18h32
  3. Couper 1 ligne sur plusieurs lignes
    Par Metalman dans le forum JCL - SORT
    Réponses: 2
    Dernier message: 27/03/2014, 10h39
  4. Réponses: 5
    Dernier message: 02/09/2010, 17h15
  5. disque dur installé mais pas d'icône sur le bureau
    Par stephan1 dans le forum Composants
    Réponses: 2
    Dernier message: 14/12/2005, 11h17

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