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 :

[AWK] problème while getline break


Sujet :

Shell et commandes GNU

  1. #1
    DIE
    DIE est déconnecté
    Membre du Club
    Profil pro
    Inscrit en
    Août 2005
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 101
    Points : 66
    Points
    66
    Par défaut [AWK] problème while getline break
    Bonjour à tous,
    Je tourne en rond avec une petite boucle en awk
    Je souhaite afficher le contenu d'un fichier en supprimant la ligne commençant par DDF et ne contenant pas RSALS301CT12
    puis les lignes suivantes (qui ne commencent pas par DDF) jusqu'au prochain DDF et autres lignes qu'il faudra afficher.
    Mon problème vient de l'instruction break qui sort de la boucle car le critère n'est pas rencontré (normal) mais la ligne DDF suivante n'étant alors pas traitée.

    Fichier source :
    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
    DDF01RSISR3  FK5U    RSALS301CT800100002720181206005541529R0032018
    CT80
    CT80
    DDF01RSISR3  FK5U    RSALS301CT130100002220181206005724696R0032018
    CT13
    DDF01RSISR3  FK5U    RSALS301CT120100002620181206005247525R0032018
    CT12
    CT12
    CT12
    DDF01RSISR3  FK5U    RSALS301CT350100002420181206005728097R0032018
    CT35
    DDF01RSISR3  FK5U    RSALS301CT510100002620181206005188422R0032018
    CT51
    DDF01RSISR3  FK5U    RSALS301CT210200002320181206004754950R0032018
    CT21
    Ma commande
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk '/^DDF/&&!/RSALS301CT12/ {print ; while (getline line) {if(line !~/DDF/) print line;else break}}' a.txt
    Le résultat
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    DDF01RSISR3  FK5U    RSALS301CT800100002720181206005541529R0032018
    CT80
    CT80
    DDF01RSISR3  FK5U    RSALS301CT350100002420181206005728097R0032018
    CT35
    DDF01RSISR3  FK5U    RSALS301CT210200002320181206004754950R0032018
    la ligne DDF01RSISR3 FK5U RSALS301CT120100002620181206005247525R0032018 et les suivantes ne sont pas traitées
    et c'est ce que je voulais, mais d'autres sont également passées à la trappe (une sur deux à cause du break)
    Je pense que ma commande n'est pas appropriée à ce cas ?
    ############
    # KSH sous AIX #
    ############

  2. #2
    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,

    plutôt que de jongler avec getline j'aurai tendance à positionner un flag pour déterminer s'il faut afficher la ligne ou non :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $ awk '/^DDF/ && !/RSALS301CT12/ {flag=1; next} /^DDF/ {flag=0} !flag {print}' fichier
    DDF01RSISR3  FK5U    RSALS301CT120100002620181206005247525R0032018
    CT12
    CT12
    CT12
    • si on trouve une ligne foireuse on ne l'affiche pas, on positionne le flag à 1 et on passe à la ligne suivante avec next, sinon...
    • ...à la prochaine ligne commençant par "DDF" on repositionne le flag à 0
    • si le flag vaut 0, alors on affiche la ligne

  3. #3
    Expert éminent sénior Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 243
    Points : 13 458
    Points
    13 458
    Par défaut
    Bonjour

    Si c'est juste pour séparer les blocs DDF, utilise une seule commande sed :
    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
    $ sed -z 's/\nDDF/\n&/g' fichier.txt
    DDF01RSISR3  FK5U    RSALS301CT800100002720181206005541529R0032018
    CT80
    CT80
     
    DDF01RSISR3  FK5U    RSALS301CT130100002220181206005724696R0032018
    CT13
     
    DDF01RSISR3  FK5U    RSALS301CT120100002620181206005247525R0032018
    CT12
    CT12
    CT12
     
    DDF01RSISR3  FK5U    RSALS301CT350100002420181206005728097R0032018
    CT35
     
    DDF01RSISR3  FK5U    RSALS301CT510100002620181206005188422R0032018
    CT51
     
    DDF01RSISR3  FK5U    RSALS301CT210200002320181206004754950R0032018
    CT21
    🎅 Joyeux noël ! 🎅
    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

  4. #4
    DIE
    DIE est déconnecté
    Membre du Club
    Profil pro
    Inscrit en
    Août 2005
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 101
    Points : 66
    Points
    66
    Par défaut
    Merci de vos réponses rapides
    En testant vos codes je viens de m'apercevoir que je me suis trompé dans l'énoncé du problème

    A la place de :
    Je souhaite afficher le contenu d'un fichier en supprimant la ligne commençant par DDF et ne contenant pas RSALS301CT12
    Je voulais dire :
    Je souhaite afficher le contenu d'un fichier en supprimant la ligne commençant par DDF ET contenant RSALS301CT12
    puis les lignes suivantes (qui ne commencent pas par DDF) jusqu'au prochain DDF et autres lignes qu'il faudra afficher.

    En fait le résultat inverse de ta commande BufferBob, j'ai bien essayé de la modifié mais je n'arrive pas au bon résultat

    Que signifie le !flag dans ta commande ?
    ############
    # KSH sous AIX #
    ############

  5. #5
    Expert éminent sénior Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 243
    Points : 13 458
    Points
    13 458
    Par défaut
    A la place de :
    Je souhaite afficher le contenu d'un fichier en supprimant la ligne commençant par DDF et ne contenant pas RSALS301CT12
    Je voulais dire :
    Je souhaite afficher le contenu d'un fichier en supprimant la ligne commençant par DDF ET contenant RSALS301CT12
    Il suffit de supprimer le premier point d'exclamation.

    Que signifie le !flag dans ta commande ?
    Il avait pourtant pris le temps de détailler.
    C'est écrit !
    "si le flag vaut 0, " ...

    D'ailleurs, la dernière accolade de la commande est facultative puisque c'est l'action par défaut.
    Mais on comprend mieux comme ça. Merci BufferBob.
    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

  6. #6
    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 DIE Voir le message
    Je souhaite afficher le contenu d'un fichier en supprimant la ligne commençant par DDF ET contenant RSALS301CT12
    pourtant dans ton premier post ton explication était raccord avec ton code, et j'ai finalement repris exactement la même condition /^DDF/&&!/RSALS301CT12/, ça m'étonne d'autant que tu ne parviennes pas à modifier facilement :

    Citation Envoyé par DIE Voir le message
    (...) en supprimant la ligne commençant par DDF et ne contenant pas RSALS301CT12
    (...)
    Ma commande
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk '/^DDF/&&!/RSALS301CT12/ (...)
    pour le reste Flodelarab a déjà répondu, le point d'exclamation est un not logique, il suffit de le faire sauter /^DDF/ && /RSALS301CT12/ voire même directement /^DDF.+RSALS301CT12/, quant à !flag c'est une expression vraie (true) lorsque "there's not flag", donc quand flag vaut zéro.

    Citation Envoyé par Flodelarab Voir le message
    Merci BufferBob.
    de rien copain merci à toi !...

  7. #7
    DIE
    DIE est déconnecté
    Membre du Club
    Profil pro
    Inscrit en
    Août 2005
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 101
    Points : 66
    Points
    66
    Par défaut
    Merci pour vos explications claires

    J'ai testé pour supprimer plusieurs entêtes et c'est OK à présent

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk '/^DDF.+(RSALS301CT12|RSALS301CT35|RSALS301CT51)/ {flag=1; next} /^DDF/ {flag=0} !flag' fichier.txt
    ############
    # KSH sous AIX #
    ############

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

Discussions similaires

  1. Problème avec word-break
    Par kevinf dans le forum Mise en page CSS
    Réponses: 2
    Dernier message: 28/10/2007, 15h42
  2. Réponses: 1
    Dernier message: 21/08/2006, 19h17
  3. Problème avec getline
    Par acieroid dans le forum C++
    Réponses: 6
    Dernier message: 26/04/2006, 10h16
  4. Réponses: 6
    Dernier message: 24/01/2006, 13h31
  5. Problème avec getline().
    Par bouceka dans le forum C++
    Réponses: 4
    Dernier message: 23/01/2006, 18h23

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