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 :

Éliminer les doublons dans un fichier sous bash


Sujet :

Shell et commandes GNU

  1. #1
    Nouveau membre du Club
    Femme Profil pro
    Inscrit en
    Janvier 2013
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2013
    Messages : 37
    Points : 27
    Points
    27
    Par défaut Éliminer les doublons dans un fichier sous bash
    Bonjour les gens,

    J'ai un fichier constitué de 3 colonnes: (V est la distance entre deux points (exemple V1 est la distance entre ces deux point A B)

    fichier.txt
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    A B V1
    A C V2
    D C V3
    B A V1
    D E V2
    G G V4
    je veux éliminer deux types de doublons:
    G G et B A vu que j'ai déjà A B et A B=B A

    Comment peut-on faire ça sous bash?

    J'ai réussi à éliminer les G G (X X...) avec la commande suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Egaux=$(awk '$1 != $2 {print $0}' $resdir/fichier.txt)
    echo "$Egaux" > $resdir/resultat.txt
    Pour la deuxième condition, éliminer B A si on a A B (car ça veux dire la même chose)
    je ne vois pas comment faire ça!!!

    Quelqu'un peut m'aider ?

    Merci par avance

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 389
    Points
    19 389
    Par défaut
    Bonjour,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk '{if($1!=$2 && !($1"@"$2 in a) && !($2"@"$1 in a)){ print $0; a[$1,$2]++}}' SUBSEP="@" fichier
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Rédacteur

    Avatar de ok.Idriss
    Homme Profil pro
    IS Consultant
    Inscrit en
    Février 2009
    Messages
    5 220
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2009
    Messages : 5 220
    Points : 19 452
    Points
    19 452
    Par défaut
    Bonsoir.

    J'ajoute mes petites contributions...

    En awk avec tableau associatif (un peu le même style que N_Bah en moins bien mais j'utilise souvent ce genre de choses et ça fonctionne bien ) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    [idriss@hp-dv6:~]$ cat test.txt
    A B V1
    A C V2
    D C V3
    B A V1
    D E V2
    G G V4
    [idriss@hp-dv6:~]$ awk -F " " '{if($1 != $2 && !($1";"$2 in array) && !($2";"$1 in array)){array[$1";"$2]=$0}} END {for(i in array){print array[i]}}' test.txt | sort
    A B V1
    A C V2
    D C V3
    D E V2
    [idriss@hp-dv6:~]$
    Et une solution en bash puisque tu nous a parlé de bash et non de awk (qui est préférable pour le cas présent) :

    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
    23
    24
    25
    26
    27
    28
    29
    30
    [idriss@hp-dv6:~]$ cat test.txt 
    A B V1
    A C V2
    D C V3
    B A V1
    D E V2
    G G V4
    [idriss@hp-dv6:~]$ cat test.sh
    #!/bin/bash
     
    FILE_OUT=test2.txt
    FILE_IN=test.txt
     
    touch $FILE_OUT
    while read ligne; do
        set -- $ligne
        occ="$2 $1 $3"
        if [ "$1" != "$2" ] && ! grep "$occ" $FILE_OUT > /dev/null && ! grep "$ligne" $FILE_OUT > /dev/null; then
            echo $ligne >> $FILE_OUT
        fi
    done < $FILE_IN
     
    cat $FILE_OUT | sort
    rm $FILE_OUT
    [idriss@hp-dv6:~]$ ./test.sh
    A B V1
    A C V2
    D C V3
    D E V2
    [idriss@hp-dv6:~]$
    Cordialement,
    Idriss

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 389
    Points
    19 389
    Par défaut
    en awk, les tableaux sont toujours associatifs. Du coup, ils ne sont que par hasard dans l'ordre chronologique ou numérique ou alphabétique.
    À moins que tous les indices soient numériques, et qu'on connaisse le nombre d'éléments pour faire un boucle arithmétique, il faudra utiliser asort() ou asorti() pour les ordonner; ou utiliser sort à la sortie de awk.

    par contre, ton code shell ne contient pas d'éléments bash.
    tu pourrais lire la ligne dans un tableau indexé
    utiliser un tableau associatif en te servant des premier et deuxième champs du tableau indexé en tant qu'indice avec un séparateur quelconque (mettons SEP=';')...
    créer une fonction in_array (pour éviter les grep), qui bouclerait sur les indices du tableau associatif, et ayant comme premier argument les deux premiers champs courants concaténés avec le séparateur défini
    ...
    et toujours afficher les données directement après avoir été testées, pour ne pas avoir à trier (un fichier temporaire)

    mouais c'est pas hyper clair.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  5. #5
    Rédacteur

    Avatar de ok.Idriss
    Homme Profil pro
    IS Consultant
    Inscrit en
    Février 2009
    Messages
    5 220
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2009
    Messages : 5 220
    Points : 19 452
    Points
    19 452
    Par défaut
    Bonjour.

    Merci pour toutes ces précisions

    Citation Envoyé par N_BaH Voir le message
    et toujours afficher les données directement après avoir été testées, pour ne pas avoir à trier (un fichier temporaire)
    De toute façon si le fichier d'entrée est déjà trié comme il semble être le cas, alors le sort de mon script est inutile. Après oui le fichier temporaire c'est pas très beau.

    Sinon les grep dans un script ça ne me gène pas trop mais je comprends ton point de vue et ta manière de faire qui te rendent indépendant des commandes externes (d'ailleurs j'étais pas obligé d'appeler bash avec cette syntaxe, sh ou ksh seraient passé aussi mais bon comme je suis sous Linux, je préfère utiliser le shell par défaut).

    Idriss

  6. #6
    Nouveau membre du Club
    Femme Profil pro
    Inscrit en
    Janvier 2013
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2013
    Messages : 37
    Points : 27
    Points
    27
    Par défaut
    Merci beaucoup pour vos réponses !

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    792
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 792
    Points : 1 206
    Points
    1 206
    Par défaut
    La solution proposée par N_BaH me semble aussi la plus évidente. Tant qu'à utiliser une commande externe comme grep, autant directemet utiliser awk qui est vraiment fait pour ce genre de traitement.

    On pourrait même simplement faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk '!(a[$1$2]||a[$2$1]||$1==$2){print;a[$1$2]++}' fichier
    :q :q! :wq :w :w! :wq! :quit :quit! :help help helpquit quit quithelp
    :quitplease :quitnow :leave :shit ^X^C ^C ^D ^Z ^Q QUITDAMMIT
    Jabber: ripat at im.apinc.org

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

Discussions similaires

  1. [Batch] .bat pour éliminer des doublons dans 2 fichiers
    Par Nono Sto dans le forum Scripts/Batch
    Réponses: 0
    Dernier message: 04/05/2014, 05h42
  2. éliminer les doublons dans un tableau
    Par elpatriota dans le forum VBScript
    Réponses: 3
    Dernier message: 21/03/2011, 12h46
  3. [WD12] Chercher les doublons dans un fichier texte
    Par matt1704 dans le forum WinDev
    Réponses: 17
    Dernier message: 11/06/2009, 08h31
  4. Vérifier les doublons dans un fichier texte
    Par Shyboy dans le forum Langage
    Réponses: 2
    Dernier message: 11/07/2007, 09h34
  5. [sql] [oracle] éliminer les doublons dans sum ?
    Par trungsi dans le forum Langage SQL
    Réponses: 14
    Dernier message: 04/03/2005, 12h29

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