Forum Linux.général comparaison de deux fichiers

Posté par  (site web personnel) .
Étiquettes : aucune
0
4
oct.
2012

Bonjour,

Je cherche un moyen de trouver le texte commun de deux fichiers.

J'ai deux fichiers f et g, qui ont beaucoup de partie semblable. Je cherche à créer le fichier x qui contiendrait toutes les lignes présentes dans f et g. Ceci afin de pouvoir appliquer deux patchs sur x, l'un qui créerait g, l'autre qui créerait f.

Voici un schéma si ce n'est pas clair:

f  g
 \/
 x

J'ai essayé de jouer diff, mais je n'ai pas trouvé comment faire cela simplement.

Si quelqu'un a une idée, merci de la partager !

  • # Intersection de fichier

    Posté par  . Évalué à 2.

    Se qu'il te faut, c'est pas la différence mais l'intersection des deux fichiers. Une petite recherche sur le web et tu tombe sur :

    for i in `cat file1 | awk {'print $1'}`
    do
    grep ${i} file2
    done
    
    

    Ou en une ligne :

    awk 'NR==FNR{a[$0]=$0;next}a[$0]' file1 file2
    
    

    Trouvé sur : > http://www.unix.com/shell-programming-scripting/63272-find-intersection-between-two-files.html

    • [^] # Re: Intersection de fichier

      Posté par  . Évalué à 3.

      Faut espérer ne pas avoir de lignes similaires dans des contextes différents alors.
      Le lien propose aussi "comm" que je ne connais pas trop bien, mais il semble que
      comm -12 --nocheck-order fil1 fil2 pourrait faire l'affaire. A voir pour la remarque sur les lignes similaires.

      • [^] # Re: Intersection de fichier

        Posté par  (site web personnel) . Évalué à 2.

        Effectivement, la comparaison ligne à ligne ne fonctionne pas dans mon cas.

        Comm ne fonctionne correctement que lorsque les lignes sont triées, et donc ne convient pas non plus.

  • # grep cut sort uniq

    Posté par  . Évalué à 2.

    Si tu veux vraiment faire une comparaison ligne à ligne, tu peux écrire ceci :

    grep -n "" a b | cut -d':' -f2- | sort -n | uniq -d | cut -d':' -f2-
    
    

    Par contre, s'il s'agit de comparer des textes dans lesquels il y a des blocs en moins ou en plus, il faudra utiliser diff et éliminer toutes les lignes marquées dans le fichier de sortie.

    • [^] # Re: grep cut sort uniq

      Posté par  (site web personnel) . Évalué à 2.

      Par contre, s'il s'agit de comparer des textes dans lesquels il y a des blocs en moins ou en plus, il faudra utiliser diff et éliminer toutes les lignes marquées dans le fichier de sortie.

      C'est ce que je voulais faire au début. Malheureusement, diff indique les numéros de lignes de chaque modification. Autant je peux supprimer les lignes qui commencent par ">" simplement, autant recalculer tous les numéros de ligne est tout de suite moins simple…

      À moins qu'une option de diff (ou de patch) me permette d'éviter cela…

  • # facile ! (ou j'ai pas compris)

    Posté par  (site web personnel) . Évalué à 3.

    man comm

  • # join

    Posté par  . Évalué à -3.

    main join

    • [^] # Re: join

      Posté par  . Évalué à 3.

      Alors là, pour le coup, je ne vois vraiment pas le rapport.

      • [^] # Re: join

        Posté par  . Évalué à 2.

        Pardon, j'ai lu trop vite …

  • # Pourquoi x + 2 patchs ?

    Posté par  (site web personnel) . Évalué à 2. Dernière modification le 04 octobre 2012 à 16:23.

    C'est pas plus simple d'avoir f, et un seul patch pour créer g à partir de f ?

    Python 3 - Apprendre à programmer dans l'écosystème Python → https://www.dunod.com/EAN/9782100809141

    • [^] # Re: Pourquoi x + 2 patchs ?

      Posté par  (site web personnel) . Évalué à 2.

      Parce que j'ai l'impression que plutôt que d'avoir des patchs, je devrais utiliser une bibliothèque. Et x serait la bibliothèque dont j'ai besoin.

      Pour y réfléchir, je voulais avoir x sous les yeux justement. Je pensais que ce serait simple…

  • # Résolu à la main

    Posté par  (site web personnel) . Évalué à 4. Dernière modification le 04 octobre 2012 à 16:57.

    Finalement, c'est la ligne awk qui donne le résultat le plus exploitable manuellement.

    J'ai donc fait ainsi:

    awk 'NR==FNR{a[$0]=$0;next}a[$0]' f g > x
    diff x f > xtof
    
    

    Et j'ai nettoyé x à la main en supprimant en son sein toutes les lignes commençant par "<" dans xtof.

    Ceci fait, l'absence de "<" dans diff x f et diff x g m'a permis de vérifier que x est bien l'intersection entre f et g.

    Merci à tous !

  • # 4 solutions

    Posté par  (site web personnel) . Évalué à 2.

    http://mywiki.wooledge.org/BashFAQ/036

    Is it a Bird? Is it a Plane?? No, it's Super Poil !!!

    • [^] # Re: 4 solutions

      Posté par  (site web personnel) . Évalué à 2.

      C'est sympathique de continuer à m'aider, mais sur les quatre solutions, deux sont listées ci-dessus, et aucune ne convient à mon problème, puisqu'elles ne prennent pas en compte le contexte.

      La vraie solution sera à base de diff, et consistera à modifier le diff par un script bien écrit, pour n'en conserver que les lignes à supprimer.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.