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 :

[KSH][AWK] Suppression de lignes si doublon d'un champ


Sujet :

Shell et commandes GNU

  1. #1
    Membre confirmé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Novembre 2011
    Messages
    101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Novembre 2011
    Messages : 101
    Par défaut [KSH][AWK] Suppression de lignes si doublon d'un champ
    Bonjour,

    Voici la situation.

    Nous recevons régulièrement un fichier sur un serveur.
    Il y a un script qui le formate avant de rediriger le résultat.

    Voici une ébauche du fichier reçu.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    ...
    23456987452;20130529172547;A;|P;UO;|490000000;|252525478987452;002...
    12145214756;20130529172550;A;|P;UO;4908500001|490000001;|20258746987412;006...
    51025412541;20130529172550;A;|P;UO;|490000000;|203687445212112;006...
    ...
    Le champs qui nous intéresse est en gras [numéro de téléphone]
    Séparateur primaire ';' [6ème champs]
    Séparateur secondaire '|' [à droite du pipe]

    Il faut faire évoluer le script pour ne plus avoir de doublons de numéro de téléphone en ne gardant que le plus neuf (le plus bas dans la liste), ne pas traiter les autres.

    Je pensais donc à faire un nettoyage à l'aide d'un AWK. J'ai trouvé quelques fonctions qui permettent de gérer les doublons de lignes, mais pas d'éviter les traitements d'une ligne complète si un champ est en doublon. (De plus, je pense qu'il faudra lire le fichier à l'envers pour ce nettoyage, non?).


    Merci!

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

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

    c'est pas hyper clair

    on peut avoir plus de lignes d'exemple, et la sortie attendue correspondante ?

    tu précises KSH... est-ce que tu es sur GNU/Linux ?
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 390
    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 390
    Par défaut
    Bonjour,

    Si tu remplis un tableau de hash dont chaque clé est le numéro de téléphone, au final tu auras l'unicité des lignes par rapport a son numéro de téléphone et dans ce cas pas besoin de lire le fichier à l'envers.

  4. #4
    Membre confirmé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Novembre 2011
    Messages
    101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Novembre 2011
    Messages : 101
    Par défaut
    N_BaH :
    Oui, sous Linux.
    Voici quelques lignes supplémentaire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    ...
    23456987452;20130529172547;A;|P;UO;|490000000;|252525478987452;002...
    12145214756;20130529172550;A;|P;UO;4908500001|490000001;|20258746987412;006...
    51025412541;20130529172550;A;|P;UO;|490000000;|203687445212112;006...
    51522411541;20130529172552;A;|P;UO;|490000520;|203687445212151;006...
    74556852541;20130529172558;A;|P;UO;490000520|490000530;|203687448512112;006...
    51025411254;20130529172559;A;|P;UO;|490000450;|203687445212222;006...
    44425412415;20130529172300;A;|P;UO;|490000530;|203687445212142;006...
    ...
    Dans notre cas, il faut supprimer les lignes suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    23456987452;20130529172547;A;|P;UO;|490000000;|252525478987452;002...
    74556852541;20130529172558;A;|P;UO;490000520|490000530;|203687448512112;006...
    Qui sont les 2 plus vieilles avec le même numéro de téléphone à droite du pipe du 6ème champ.

    disedorgue
    Quelle serait la commande? Je débute avec le awk...

    Merci.

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 694
    Par défaut
    Quelle serait la commande?
    on n'a pas encore décidé; on peut avoir la carte s'il vous plaît ?



    Code pseudo-code awk : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SI 6èmeChamp contient "|"
    ALORS
       splitter le 6èmeChamp
       indice = 2émePartieDu6èmeChamp
    SINON
       indice= 6èmeChamp
    FINSI
    tableau[indice] = ligneEntière
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  6. #6
    Membre confirmé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Novembre 2011
    Messages
    101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Novembre 2011
    Messages : 101
    Par défaut
    Le 6ème champs contient toujours un pipe, et c'est toujours la valeur après ce pipe qui doit être unique (elle ne sera jamais nulle dans notre fichier).


    Je sais déjà qu'on peut utiliser ceci dans notre awk -F";"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    split($6,list_num,"|");
    new_num=gsmnum[2];
    Il faut maintenant que cette valeur soit unique, et surtout, garder la plus récente, nous avons pour cela la date dans le champ $2 au format YYYYMMDDHHmmSS. (Mais de base le fichier est trié du plus ancien au plus récent).

    ...


    Merci.

    Et désolé, pas de carte ici, on ne sert que du café.

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 694
    Par défaut
    avec un tableau, les valeurs uniques des différents indices écraseront les précédents (dans le sens de lecture du fichier tel que présenté plus haut) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    split($6,a,"|")
    tableau[a]=$0
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  8. #8
    Membre confirmé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Novembre 2011
    Messages
    101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Novembre 2011
    Messages : 101
    Par défaut
    Ha oui, je vois!

    Je crois en effet que ça peut résoudre le problème.


    Dans le AWK :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    split($6,list_num,"|");
    new_num=gsmnum[2];
    tableau[new_num]=$0;
    Notre tableau contient bien toutes les lignes dont nous avons besoin.

    Pour l'imprimer, cette solution serait-elle correct?

    Pour au final avoir ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    awk -F";"  'BEGIN {
    split($6,list_num,"|");
    new_num=gsmnum[2];
    tableau[new_num]=$0;
    } END {printf tableau}' > $cleanedfilename
    Merci encore, je vais faire quelques tests dans ce sens.
    Et je dis ce qu'il en est.

  9. #9
    Membre confirmé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Novembre 2011
    Messages
    101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Novembre 2011
    Messages : 101
    Par défaut
    J'ai réalisé un test unitaire avec simplement ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #!/usr/bin/ksh
     
    awk -F";"  'BEGIN {split($6,list_num,"|");
    new_num=gsmnum[2];
    tableau[new_num]=$0;} END {printf tableau}' mon_input.lst > mon_input_cleaned.lst
     
    exit 0;

    Mon input contient plusieurs centaines de lignes (dont quelques doublons) mais mon fichier de sortie est vide.
    Est-ce que le problème viendrait du : printf tableau...?

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 694
    Par défaut
    pour afficher un tableau, il faut itérer dessus :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    END{for (i in tableau)print tableau[i]}
    cf. manuel de l'utilisateur awk
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  11. #11
    Membre confirmé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Novembre 2011
    Messages
    101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Novembre 2011
    Messages : 101
    Par défaut
    Ok, c'est parfais ainsi.
    Il faut supprimer le BEGIN, sinon il ne passe qu'une fois.

    Il faut également que je fasse un sort à la fin pour remettre les résultats dans l'ordre d'inscription.

    Mais avec tout ça, j'ai le résultat souhaité.

    Merci!

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 694
    Par défaut
    Il faut également que je fasse un sort à la fin pour remettre les résultats dans l'ordre d'inscription.
    awk possède des fonctions de tri de tableaux.
    et gawk, un paramétrage de PROCINFO permet de définir sur quoi opère tel ou tel autre ordre de tri.
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  13. #13
    Membre confirmé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Novembre 2011
    Messages
    101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Novembre 2011
    Messages : 101
    Par défaut
    Merci N_BaH,

    Je ne connais pas vraiment ces fonctions... En l'occurence, nous avons déjà une fonction très propre de tri qui gère tous les éléments nécessaires, y faire appel n'est pas un problème.

    Mais j'y penserai lors de prochains développement en awk.

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

Discussions similaires

  1. Réponses: 13
    Dernier message: 27/05/2015, 21h51
  2. [AC-2000] Suppression de premières lignes des doublons dans une requête
    Par jyoboue2008 dans le forum Access
    Réponses: 3
    Dernier message: 17/03/2014, 19h55
  3. [XL-2003] Suppression de lignes par masques & doublons
    Par microb76 dans le forum Macros et VBA Excel
    Réponses: 10
    Dernier message: 14/06/2012, 11h50
  4. [ksh] suppression de ligne si champs en double
    Par KSH_user dans le forum Shell et commandes GNU
    Réponses: 4
    Dernier message: 11/05/2009, 22h03
  5. AWK suppression d'espace dans une ligne
    Par falcon dans le forum Shell et commandes GNU
    Réponses: 3
    Dernier message: 16/07/2008, 10h52

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