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 :

Comparer le contenu de 2 fichiers et récupérer le résultat


Sujet :

Shell et commandes GNU

  1. #1
    Membre averti
    Femme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 54
    Par défaut Comparer le contenu de 2 fichiers et récupérer le résultat
    Bonjour,

    J'ai 2 fichiers texte "pilotes" et "machines" contenant chacun des noms de serveurs (un seul nom par ligne) dont voici respectivement le contenu :

    Fichier "pilotes" :

    assid01
    albidy2
    maiss4ips
    saytyl2
    massy54
    ......., etc.

    Fichier "machines" :

    qunr01n
    bitric7
    assid01
    lasmer9
    albidy2
    zebrai23
    albin30
    maiss4ips
    ertibis08
    saytyl2
    massy54
    .........,etc.

    Le fichier "pilotes" est censé être un sous ensemble de du fichier "machines",... mais on a des surprises !
    Globalement il s'agit de comparer ligne par ligne le contenu du fichier "pilotes" avec celui du fichier "machines", autrement dit trouver tous les noms qui se trouvent à la fois dans chacun des 2 fichiers.

    Mes questions :
    1- comment puis-je vérifier qu'il y a pour chaque nom dans "pilotes" le même nom dans "machines"?
    2- Puis, si c'est vrai écrire chaque nom trouvé dans un fichier "résultats", et si pour un nom lambda dans "pilotes" on ne trouve pas le même nom dans "machines", on écrit alors une phrase : " le nom : $nom du fichier "pilotes" n'existe pas dans le fichier "machines".

    D'avance merci de votre aide

  2. #2
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Par défaut
    Salut,

    Ça ne fait exactement ce que tu veux dans la mesure où ça crée 2 fichiers (bon et mauvais), mais ça fait quand même ce que tu demandes :

    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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    $ cat pilotes 
    assid01
    albidy2
    maiss4ips
    saytyl2
    massy54
    .........,etc.
    tttrreee
     
    $ cat machines 
    qunr01n
    bitric7
    assid01
    lasmer9
    albidy2
    zebrai23
    albin30
    maiss4ips
    ertibis08
    saytyl2
    massy54
    .........,etc.
     
    $ fgrep -f pilotes machines > bon
     
    $ fgrep -vf machines pilotes > mauvais
     
    $ cat bon 
    assid01
    albidy2
    maiss4ips
    saytyl2
    massy54
    .........,etc.
     
    $ cat mauvais 
    tttrreee
     
    $

  3. #3
    Membre averti
    Femme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 54
    Par défaut
    Grand Merci. Ca me donne exactement ce que je voulais !
    Mais est ce que je peux avoir tous les résultats dans un seul fichier, de telle sorte que le résultat de votre exeple s'affiche comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $ cat monfichier
    assid01
    albidy2
    maiss4ips
    saytyl2
    massy54
    le nom :  tttrreee du fichier "pilotes" n'existe pas dans le fichier "machines"

  4. #4
    Membre Expert
    Avatar de Loceka
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    2 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 2 276
    Par défaut
    Essaye ça (j'ai pas testé) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    fgrep -f pilotes machines > resultat
    fgrep -vf machines pilotes | sed -re 's/^(.*)$/$1 du fichier "pilotes" n\'existe pas dans le fichier "machines"/' >> resultat

  5. #5
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Par défaut
    Salut,

    Citation Envoyé par Loceka Voir le message
    Essaye ça (j'ai pas testé) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    fgrep -f pilotes machines > resultat
    fgrep -vf machines pilotes | sed -re 's/^(.*)$/$1 du fichier "pilotes" n\'existe pas dans le fichier "machines"/' >> resultat
    La sous-expression n'est pas nécessaire à partir du moment où c'est la ligne entière qui nous intéresse. De plus la référence à une sous expression c'est "\1" et non pas "$1"

    Il y a aussi l'apostrophe qui pose problème, même en l'échappant je n'arrive pas à la faire accepter, seule solution sortir de sed, la protéger avec des quotes doubles et revenir dans sed :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fgrep -vf machines pilotes | sed  's/.*/le nom : "&" du fichier "pilotes" n'"'"'existe pas dans le fichier "machines"/' >> resultat

  6. #6
    Membre averti
    Femme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 54
    Par défaut
    Je viens de rencontrer un problème :

    Est-ce que le fichier "bon" doit contenir le même nombre de ligne (ou de noms) que dans le fichier "pilotes" ? Dans mon cas, l'équivalent du fichier "bon" contient moins de ligne que "pilotes". D'où cela pourrait-il venir à votre avis ? Rechercher dans l'un ou l'autre des fichier est fastidieux, car ce sont des fichiers trop gros...

  7. #7
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Par défaut
    Citation Envoyé par bras39 Voir le message
    Est-ce que le fichier "bon" doit contenir le même nombre de ligne (ou de noms) que dans le fichier "pilotes" ?
    Ben pas forcément, c'est justement le but de ta demande initiale
    Je te cite :Le fichier "pilotes" est censé être un sous ensemble de du fichier "machines",... mais on a des surprises !

    Dans mon cas, l'équivalent du fichier "bon" contient moins de ligne que "pilotes". D'où cela pourrait-il venir à votre avis ?
    Normalement tu devrais retrouver les fichiers manquants dans le fichier "mauvais"

  8. #8
    Membre averti
    Femme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 54
    Par défaut
    Citation Envoyé par zipe31 Voir le message
    Normalement tu devrais retrouver les fichiers manquants dans le fichier "mauvais"
    C'est ça que je ne comprends pas du tout car un cat du fichier mauvais ne retourne rien ! Et pourtant ne serait-ce en comptant le nombre lignes : j'en ai beaucoup plus dans "pilotes" que dans "bon"...

  9. #9
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Par défaut
    Dans mon exemple avec les fichiers employés ça marche.

    Maintenant sans avoir tous les éléments entre les mains, et notamment les vrais fichiers, je ne sais que te dire

  10. #10
    Membre averti
    Femme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 54
    Par défaut
    Citation Envoyé par zipe31 Voir le message
    Dans mon exemple avec les fichiers employés ça marche.

    Maintenant sans avoir tous les éléments entre les mains, et notamment les vrais fichiers, je ne sais que te dire
    J'ai compris pourquoi ça ne marchait pas ! En fait "fgrep" est visiblement très sensible à toute sorte d'espace qui précéde ou suive les noms dans un fichier. En l'occurence, il ne prenait pas en compte tous les noms qui sont suivis d'un espace ou d'une tabulation. C'est pourquoi tout les noms suivi d'un espace dans le fichier "pilotes" sont tout simplement ignorés sans toutefois les reporter dans le fichier "mauvais" !
    Je déviene que ça doit être également le cas si on avait des espaces ou autres dans le fichier "machines" (je testerai plus tard cette hyptothèse )...

    Comment peut-on s'en sortir de cette situation de telle sorte que les mots/noms (ou lignes) suivis ou précédés d'un espace/tabulation dans l'un ou l'autre des 2 fichiers à comparer puissent être pris en compte dans tous les cas ?

    D'avance Merci

  11. #11
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Par défaut
    Citation Envoyé par bras39 Voir le message
    J
    Comment peut-on s'en sortir de cette situation de telle sorte que les mots/noms (ou lignes) suivis ou précédés d'un espace/tabulation dans l'un ou l'autre des 2 fichiers à comparer puissent être pris en compte dans tous les cas ?

    D'avance Merci
    Pour enlever les espaces avant et après :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed 's/^[ \t]*//;s/[ \t]*$//' fichier_entrée > fichier_sortie

  12. #12
    Membre averti
    Femme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 54
    Par défaut
    Citation Envoyé par zipe31 Voir le message
    Pour enlever les espaces avant et après :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed 's/^[ \t]*//;s/[ \t]*$//' fichier_entrée > fichier_sortie
    Ca a marché ! Mille mercis...

    Deux petites questions au passage :

    - Comment dois-je faire pour supprimer du fichier "machines" tous les noms qui figurent dans le fichier "pilotes" et écrire le résultat dans un nouveau fichier ?

    - Supposons que mon fichier "pilotes" est composé de 3 colones de noms séparés par soit des tabulations soit par des espaces simples(ou doubles), comment puis-je :
    - Supprimer successivement chacune des colones ? ex. : si je supprime la prmière colone, il reste dans mon fichier 2 colones, et ainsi de suite
    - Récupérer séparément une seule colone et la mettre dans un autre fichier
    - récupérer seulement 2 colones et les copier dans un fichier, etc. jusqu'à la récupération de la 3ème colone...

  13. #13
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 875
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par bras39 Voir le message
    - Comment dois-je faire pour supprimer du fichier "machines" tous les noms qui figurent dans le fichier "pilotes" et écrire le résultat dans un nouveau fichier ?
    Salut
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    grep -vf pilotes machines >new

    Citation Envoyé par bras39 Voir le message
    - Supposons que mon fichier "pilotes" soit composé de 3 colones de noms séparés par soit des tabulations soit par des espaces simples(ou doubles), comment puis-je :
    - Supprimer successivement chacune des colones ? ex. : si je supprime la prmière colone, il reste dans mon fichier 2 colones, et ainsi de suite
    Sous Unix, une règle prévaut c'est d'avoir des fichiers toujours bien formatés. Tu as suffisamment d'outils te permettant de bien calibrer tes fichiers. Parce qu'avec "soit des espaces, soit des tabulations" ben c'est pas top. Enfin awk s'en sort malgré tout...
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    exec 3<pilotes
    rm -f pilotes
    cat 0<&3 |awk '{print $2 $3}' >pilotes

    Citation Envoyé par bras39 Voir le message
    - Récupérer séparément une seule colone et la mettre dans un autre fichier
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    awk '{print $x}' pilotes >autre_fichier
    (x étant le n° de ta colonne)

    Citation Envoyé par bras39 Voir le message
    - récupérer seulement 2 colones et les copier dans un fichier, etc. jusqu'à la récupération de la 3ème colone...
    Ca veut dire quoi "jusqu'à la récupération de la 3° colonne" ???
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  14. #14
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Par défaut
    Salut,

    Citation Envoyé par Sve@r Voir le message
    Salut
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    grep -vf pilotes machines >new
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    fgrep -vf pilote machines >new
    
    ou
    
    grep -F -vf pilotes machines >new
    Sans quoi ça ne le fait pas

  15. #15
    Membre averti
    Femme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 54
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Ca veut dire quoi "jusqu'à la récupération de la 3° colonne" ???
    Bonjour,

    J'apprécie énormément vos petits commentaires explicatifs, ils me permettent vraiment de comprendre de quoi il s'agit, c'est très pédagogique. Je découvre le shell, je suis désolé d'être neuneu....

    Je voudrai aussi dire que mes fichiers proviennent pour beaucoup d'Excel, fichiers texte wordpad et notespad, word, etc, c'est pourquoi...



    Par rapport à ta question, je voudrais juste indiquer une progression dans le precessus de suppression et de récupération des colones : à chaque fois que je récupère (pour copier dans un nouveau fichier) ou que je supprime une colone (jusqu'à la suppression ou la récupération de la 3ème colone), les autres lignes restent comme elle est dans mon fichier pilotes.

    Je rencontre encore cette situation :
    mon fichier pilotes comportent 4 colones séparés par 2 à plusieurs tabulations ou espaces.

    Comment faire pour y supprimer les 2 colones du milieu : a) la 4ème colone se décale pour prendre la place de la 2ème; b) elle ne bouge pas de sa position?

  16. #16
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 875
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par bras39 Voir le message
    Par rapport à ta question, je voudrais juste indiquer une progression dans le precessus de suppression et de récupération des colones : à chaque fois que je récupère (pour copier dans un nouveau fichier) ou que je supprime une colone (jusqu'à la suppression ou la récupération de la 3ème colone), les autres lignes restent comme elle est dans mon fichier pilotes.
    Non. Dans Unix, les traitements sont atomiques (tout ou rien). On part d'un fichier X fini, on lui effectue un traitement T et on obtient un fichier Y fini. Ensuite, on repart du fichier Y, on lui effectue un traitement T' et on obtient un fichier Z et etc etc etc.
    Si le fichier Y n'est pas nécessaire, alors on peut combiner les traitements T et T' par des pipes.

    Citation Envoyé par bras39 Voir le message
    Je rencontre encore cette situation :
    mon fichier pilotes comportent 4 colones séparés par 2 à plusieurs tabulations ou espaces.

    Comment faire pour y supprimer les 2 colones du milieu : a) la 4ème colone se décale pour prendre la place de la 2ème; b) elle ne bouge pas de sa position?
    Bon, là il faut aussi arrêter. Sous Unix, il y a distinguo entre "ce qui est" et "ce qui s'affiche". La philosophie est que tu as un fichier de départ. S'il te convient pas alors tu le transformes jusqu'à ce qu'il te convienne. Puis, ensuite, il ne bouge plus et tu ne fais que l'afficher sous différentes formes au travers d'outils. awk est le plus puissant de tous (car il est complètement programmable) mais il y en a d'autres comme cut, tr, pr, etc...
    Quand tu dis "supprimer" on comprend "supprimer du fichier d'origine". Mais là, il semblerait que ce soit "supprimer à l'écran" ou plus simplement "afficher d'une certaine façon". Donc là, encore awk
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    awk '{printf("%s %s\n", $1, $4)}' pilotes
    Et si tu as d'autres questions comme "ben en fait je voudrais afficher avec la 2° colonne qui prend la place de la 4° et la 1ère colonne répétée 3 fois" ben là encore awk
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    awk '{printf("%s %s %s %s %s\n", $1, $1, $1, $3, $2)}' pilotes
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  17. #17
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Août 2011
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2011
    Messages : 44
    Par défaut
    Bonjour,

    A supposer que les 2 fichiers soient triés, ceci t'affichera les lignes qui n'existent pas dans un ou l'autre des fichiers (mais pas les lignes identiques). La première colonne étant le nom se trouvant dans le fichier 'machines', la 2nde colonne celui se trouvant dans le fichier 'pilotes'. MANQUANT est affiché pour indiquer que le nom n'existe pas dans le fichier de la colonne.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    join -i -v1 -v2 -e MANQUANT -j 1 -o 1.1,2.1 machines pilotes
    Si tes fichiers ne sont pas triés :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    join -i -v1 -v2 -e MANQUANT -j 1 -o 1.1,2.1 <(sort machines) <(sort pilotes)
    Si ton shell n’accepte pas cette syntaxe, il te suffit de les trier avant

    Pour exemple :
    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
    $ cat machines 
    qunr01n
    bitric7
    assid01
    lasmer9
    albidy2
    zebrai23
    albin30
    maiss4ips
    ertibis08
    saytyl2
    massy54
     
    $ cat pilotes                                                                                                                                            
    assid01
    albidy2
    maiss4ips
    saytyl2
    massy54
    oups
     
    $ join -i -v1 -v2 -e MANQUANT -j 1 -o 1.1,2.1 <(sort machines) <(sort pilotes)
    albin30 MANQUANT
    bitric7 MANQUANT
    ertibis08 MANQUANT
    lasmer9 MANQUANT
    MANQUANT oups
    qunr01n MANQUANT
    zebrai23 MANQUANT

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 11/08/2011, 08h26
  2. Comparer le contenu de 2 fichiers txt
    Par romain_t dans le forum C
    Réponses: 5
    Dernier message: 22/10/2010, 13h35
  3. Comparer le contenu de deux fichiers
    Par Sancti_Eyes dans le forum Langage
    Réponses: 7
    Dernier message: 03/05/2009, 10h54
  4. comparer le contenu de 2 fichiers
    Par vins25 dans le forum Autres Logiciels
    Réponses: 3
    Dernier message: 20/03/2006, 07h04
  5. Comment comparer le contenu de 2 fichiers ?
    Par steph_1 dans le forum Langage
    Réponses: 4
    Dernier message: 17/06/2005, 18h38

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