Afficher les lignes communes (similitudes) de deux fichiers texte (l'opposé de diff)?


21

Diff est un excellent outil pour afficher les changements entre deux fichiers. Mais comment afficher les similitudes de deux fichiers texte (tout en ignorant les différences)?

Exemple d'entrée d'entrée:

a:
Foo Bar
X
Hello
World
42

b:
Foo Baz
Hello
World
23

Pseudo sortie (quelque chose comme ça):

@@ 2,3
=Hello World

Il ne suffit pas de trier les deux fichiers et d'utiliser la communication, car dans ce cas, les informations de ligne sont perdues.

Réponses:


24

Que diriez-vous d'utiliser diff, même si vous ne voulez pas de diff? Essaye ça:

diff --unchanged-group-format='@@ %dn,%df 
  %<' --old-group-format='' --new-group-format='' \
  --changed-group-format='' a.txt b.txt

Voici ce que j'obtiens avec vos exemples de données:

$ cat a.txt 
Foo Bar
X
Hello
World
42
$ cat b.txt 
Foo Baz
Hello
World
23
$ diff --unchanged-group-format='@@ %dn,%df
%<' --old-group-format='' --new-group-format='' \
  --changed-group-format='' a.txt b.txt
@@ 2,3
Hello
World

2
Vous pouvez éviter d'incorporer une nouvelle ligne littérale comme celle-ci:...%df'$'\n''%<'...
pause jusqu'à nouvel ordre.

1
Vous pouvez également le faire comme ceci: ... --unchanged-group-format="@@ %dn,%df%c'\012'%<" ...(Notez les guillemets doubles.)
pause jusqu'à nouvel ordre.

Super truc! Je ne connaissais pas ces options, car je viens de regarder la page de manuel diff ...
maxschlepzig

J'utilise diff --version diff (GNU diffutils) 2.8.1 Et j'obtiens l'erreur suivante: diff: options de style de sortie conflictuelles diff: Essayez `diff --help 'pour plus d'informations.
Sujay

J'obtenais «erreur: diff: options de style de sortie conflictuelles diff» parce que j'avais un alias de différence défini. Utilisez which diffpour voir si c'est votre problème.
justinjhendrick

14
grep -Fxf file1 file2

-Fsignifie correspondre à des chaînes simples (pas à des expressions rationnelles), -xsignifie uniquement des correspondances sur toute la ligne, -fsignifie prendre des «modèles» (c'est-à-dire des lignes) du fichier nommé comme argument


3
N'est-ce pas -fet -Féchangé ?. Au moins dans ma grepversion est comme ça. Je dois fournir une file2entrée à l' -fargument, comme cat file1 | grep -Fxf file2, puis fonctionne.
Birei

Cela ne fonctionne pas pour moi.
Chaminda Bandara

7

commpeut être utilisé. man commpour toutes les options, mais vous voudrez utiliser comm -12 ...pour afficher uniquement les lignes qui existent dans les deux entrées.

Comme les gens l'ont souligné, vous devez d'abord transmettre vos commentaires sort.


1
Hm, cela ne fonctionne que pour les lignes communes qui sont au même numéro de ligne dans les deux fichiers.
maxschlepzig

2
comm semble être uniquement pour les fichiers triés et ne pas donner cette sortie utile pour le cas d'utilisation de l'OP. Son exemple: $ comm -12 ab Hello World comm: le fichier 1 n'est pas dans l'ordre trié comm: le fichier 2 n'est pas dans l'ordre trié
Marcel Stimberg

@maxschlepzig: vous devez trier vos fichiers avant de les transmettre à comm.
Hemant

2
En triant, vous vous débarrassez de toutes les informations sur la position des lignes communes. Vous ne trieriez pas non plus les fichiers avant de les comparer avec diff.
Marcel Stimberg

7

Je ne pense pas qu'il existe une seule commande qui fasse ce que vous voulez qu'elle fasse. Vous pouvez cependant essayer de combiner la sortie de diffavec grep. Si vos fichiers texte contiennent aucun des caractères |, <, >, ce qui suit vous donne une sortie un peu utile:

$ diff --side-by-side a b | grep -n -v "[|<>]"
3:Hello                             Hello
4:World                             World

Essayez ceci:diff --width=155 --left-column --side-by-side a b | grep -n -v '|' | sed 's/ *($//'
pause jusqu'à nouvel ordre.

cela semble mieux - mais vous devez inclure <et> dans le grep pour vous débarrasser également des lignes ajoutées dans les deux fichiers.
Marcel Stimberg

2

Dick Grune a écrit une famille d'outils pour ce genre de chose:

http://dickgrune.com/Programs/similarity_tester/

Il existe des versions qui analysent la syntaxe de divers langages, de sorte que des choses comme les variables renommées peuvent être considérées comme inchangées.

Il est empaqueté comme similarity-testerdans Debian et Ubuntu.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.