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 :

[sed] Extraire les lignes d'un fichier en fonction de leur position


Sujet :

Shell et commandes GNU

  1. #1
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 803
    Points
    30 803
    Par défaut [sed] Extraire les lignes d'un fichier en fonction de leur position
    Bonjour,

    J'ai un programme qui vérifie le contenu d'un fichier (chargement en base de données avec transformations et conversions - le contenu originel n'est pas conservé dans l'application) et retourne une liste des numéros de lignes qui comportent une anomalie.
    Ce que je souhaiterais faire, c'est à partir de cette liste extraire du fichier de départ les lignes identifiées.

    J'ai écrit ça, mais je me dis qu'on doit pouvoir mieux faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #Le fichier .dat est le fichier d'origine, le fichier .lst celui qui liste les lignes en anomalie.
    sed -ne "$(sed -ne '/^\([^0-9]\|$\)/d;s/\(^[0-9]*\)\([^0-9]\|$\)/\1 p/' ${fichier_lst})" ${fichier_dat}
    Qu'en pensez-vous ?
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  2. #2
    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 459
    Points
    13 459
    Par défaut
    Bonjour

    Imaginons que ton fichier lst soit un fichier texte avec un numéro par ligne.
    Est-ce le numéro écrit en début de ligne dans le fichier dat ? Le numero de ligne réel ?

    Dans le premier cas, un filtre suffit:
    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
    $ cat texte.dat
    #Commentaire 6
     
    1 toto 5
    2 tata 4
    3 titi 3
    4 toto 2
    5 tutu 1
    6 tete 0
    $ cat debut.lst
    1
    3
    $ sed 's/^/^/' debut.lst|grep -f - texte.dat
    1 toto 5
    3 titi 3
    $ sed 's/^/^/' debut.lst|grep -vf - texte.dat
    #Commentaire 6
     
    2 tata 4
    4 toto 2
    5 tutu 1
    6 tete 0
    Pour le second cas,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ while read ligne; do sed -n $ligne'p' texte.dat;done <debut.lst
    #Commentaire 6
    1 toto 5
    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

  3. #3
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 803
    Points
    30 803
    Par défaut
    Merci de ta réponse rapide.

    Je suis dans le second cas.
    Pour le premier cas, j'aurais certainement utilisé join.

    Mon problème est au niveau des volumes à gérer. On parle ici d'extraire une bonne centaine de lignes d'un fichier qui en comporte plusieurs centaines de milliers, voire plusieurs millions.
    Dans la soluton que tu proposes, on lit tout le fichier autant de fois qu'il y a de lignes à extraire ; tu comprendras que j'aurais préféré le faire en une seule passe.

    Merci de m'avoir rappelé l'usage de -f - qui pourrait m'aider à résoudre d'autres problèmes
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  4. #4
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 287
    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 287
    Points : 12 744
    Points
    12 744
    Par défaut
    Bonjour,

    Une autre solution si j'ai bien compris (pas testé):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed 's/^[0-9][0-9]*$/&p/' ${fichier_lst} | sed -nf - ${fichier.dat}
    Cordialement.

  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 459
    Points
    13 459
    Par défaut
    Tu as tout à fait raison pour l'ouverture multiple du même fichier: ce n'est pas bon.

    Et puisque tu aimes "-f -", on en remet une couche:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ sed 's@$@p@' debut.lst | sed -n -f - texte.dat
    #Commentaire 6
    1 toto 5
    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

  6. #6
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 287
    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 287
    Points : 12 744
    Points
    12 744
    Par défaut
    Dans le cas de ligne vide dans fichier_lst, tu afficheras tout le fichier.dat
    Cordialement.

  7. #7
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 803
    Points
    30 803
    Par défaut
    J'étais bien parti dans la bonne direction mais j'avais un peu compliqué inutilement.
    Je ne pense pas qu'on puisse faire plus efficace.

    Merci beaucoup de votre aide à tous les deux.
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  8. #8
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 287
    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 287
    Points : 12 744
    Points
    12 744
    Par défaut
    Peut-être que si :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk 'NR == FNR {X[$1]=1;next};X[FNR]' fichier_lst fichier.dat
    Cordialement.

  9. #9
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 803
    Points
    30 803
    Par défaut
    Alors là... j'ai besoin d'une explication de texte.
    Je ne parle pas courament awk et, le peu que j'ai utilsé c'est avec un seul fichier en entrée
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  10. #10
    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 459
    Points
    13 459
    Par défaut
    Pour chaque ligne, on répond toujours à "quand?" (condition ou non) et "quoi?" (quelles instructions à exécuter, entre accolades).

    NR == FNR assure que seul le premier fichier exécutera le code entre accolades.
    next assure que le premier fichier n'exécutera rien d'autre. awk passe à la ligne suivante.

    X[FNR] est une condition. L'action sous-entendue (car absente) est {print $0;} donc l'affichage simple de la ligne.
    1 (ou plus) est vrai et 0 est faux. Et toute valeur non définie est nulle par défaut.
    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

  11. #11
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 803
    Points
    30 803
    Par défaut
    Je connais NR qui est le numéro de la ligne en cours de lecture mais que représente FNR ?
    Et comment savoir que la condition X[FNR] s'applique au second fichier ?
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  12. #12
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 287
    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 287
    Points : 12 744
    Points
    12 744
    Par défaut
    NR => Number Record
    FNR => File Number Record

    En gros, le NR est le n° de record tous fichier en entrée compris et FNR est le n° de record du fichier en cours.

    Ici, je parle de record et non de ligne car par défaut un record est une ligne mais en fait cela peut-être autre chose.
    Cordialement.

  13. #13
    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 459
    Points
    13 459
    Par défaut
    Citation Envoyé par al1_24 Voir le message
    Et comment savoir que la condition X[FNR] s'applique au second fichier ?
    Tu n'en sais rien. Il s'applique à tous. Même au 3ème, 4ème, 8ème fichier...
    Mais comme la première accolade mets fin au traitement de l'enregistrement par "next", le premier fichier ne va pas plus loin et ne verra jamais la suite.

    Tu peux empiler autant de blocs que tu veux:
    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
    $ awk '(NR%3==0){$0="toto "$0;} (NR%3==1){$0="tata "$0;} (NR%3==2){$0="titi "$0;} ($2 ~ /zozo/){$0="zozo->"$0;} 1 ' <<<"Mais 
    que
    veut
    dire
    ce
    zozo
    appelé
    zozo"
    tata Mais 
    titi que
    toto veut
    tata dire
    titi ce
    zozo->toto zozo
    tata appelé
    zozo->titi zozo
    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

  14. #14
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 803
    Points
    30 803
    Par défaut
    Merci de ces éclaircissements.
    J'aurai appris des choses aujourd'hui
    et je me coucherai moins bête ce soir.
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

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

Discussions similaires

  1. Lire les lignes d'un fichier avec csh
    Par nicolas581 dans le forum Linux
    Réponses: 4
    Dernier message: 24/03/2010, 16h38
  2. Réponses: 2
    Dernier message: 18/10/2005, 08h05
  3. Afficher les lignes d'un fichier
    Par pepere73 dans le forum C++
    Réponses: 16
    Dernier message: 21/02/2005, 22h25
  4. Extraire des lignes d'un fichier en commande bash
    Par newnew dans le forum Linux
    Réponses: 3
    Dernier message: 27/07/2004, 16h22
  5. Réponses: 3
    Dernier message: 26/04/2004, 12h51

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