2009-04-14 7 views
137

J'ai une série de fichiers texte pour lesquels j'aimerais connaître les lignes en commun plutôt que les lignes qui sont différentes entre elles. Ligne de commande unix ou windows est bien.comment afficher les lignes en commun (diff inverse)?

foo:

linux-vdso.so.1 => (0x00007fffccffe000) 
libvlc.so.2 => /usr/lib/libvlc.so.2 (0x00007f0dc4b0b000) 
libvlccore.so.0 => /usr/lib/libvlccore.so.0 (0x00007f0dc483f000) 
libc.so.6 => /lib/libc.so.6 (0x00007f0dc44cd000) 

bar:

libkdeui.so.5 => /usr/lib/libkdeui.so.5 (0x00007f716ae22000) 
libkio.so.5 => /usr/lib/libkio.so.5 (0x00007f716a96d000) 
linux-vdso.so.1 => (0x00007fffccffe000) 

Ainsi, compte tenu de ces deux fichiers ci-dessus la sortie de l'utilitaire souhaité serait semblable à file1:line_number, file2:line_number == matching text (juste une suggestion, je ne sais vraiment pas attention quelle est la syntaxe):

foo:1, bar:3 == linux-vdso.so.1 => (0x00007fffccffe000) 

merci.

+0

@ChristopherSchultz Mon erreur. 1ère ligne du 1er exemple supposé correspondre à la dernière ligne du 2ème exemple. Merci d'avoir rattrapé l'erreur; en changeant. –

+1

Une autre question similaire avec de bonnes réponses: http://unix.stackexchange.com/questions/1079/output-the-common-lines-similarities-of-two-text-files-the-opposite-of-diff – MortezaE

Répondre

169

Sur * nix, vous pouvez utiliser comm. La réponse à la question est:

comm -1 -2 file1.sorted file2.sorted 
# where file1 and file2 are sorted and piped into *.sorted 

est ici la pleine utilisation de comm:

comm [-1] [-2] [-3 ] file1 file2 
-1 Suppress the output column of lines unique to file1. 
-2 Suppress the output column of lines unique to file2. 
-3 Suppress the output column of lines duplicated in file1 and file2. 

Notez également qu'il est important de trier les fichiers avant d'utiliser comm, comme mentionné dans les pages de manuel.

+1

comm [ -1] [-2] [-3] fichier1 fichier2 -1 Supprime la colonne de sortie de lignes unique à file1. -2 Supprime la colonne de sortie des lignes uniques à file2. -3 Supprime la colonne de sortie des lignes dupliquées dans fichier1 et fichier2. – ojblass

+0

@ojblass: Ajouté ceci à la réponse. –

+3

J'ai découvert qu'il est important de trier les fichiers avant d'utiliser comm. Peut-être ajouter cela à la réponse. –

32

a été demandé ici avant: Unix command to find lines common in two files

Vous pouvez également essayer avec perl (crédit goes here)

perl -ne 'print if ($seen{$_} .= @ARGV) =~ /10$/' file1 file2 
+1

merci. J'aurais aimé accepter les deux réponses, car le perl one liner est cross plate-forme. Comm obtient le signe de tête parce que c'est plus simple. –

+0

rien de mal avec une solution alternative :) – Chris

+0

Parfait. L'utilisation du terminal cygwin sur windows et 'comm' n'était pas facilement disponible. C'était l'alternative parfaite. – Qix

11

Je viens d'apprendre la commande comm de ce fil, mais je voulais ajouter quelque chose en plus: si le les fichiers ne sont pas triés, et vous ne voulez pas toucher les fichiers d'origine, vous pouvez rediriger l'outptut de la commande de tri. Cela laisse les fichiers originaux intacts. Fonctionne à bash, je ne peux pas dire à propos d'autres coquilles.

comm -1 -2 <(sort file1) <(sort file2) 

Ceci peut être étendu pour comparer la sortie de commande, au lieu de fichiers:

comm -1 -2 <(ls /dir1 | sort) <(ls /dir2 | sort) 
35

trouvé cette réponse sur a question listed as a duplicate. Je trouve grep être plus administrateur de l'environnement que comm, donc si vous voulez juste l'ensemble des lignes correspondant (utile pour comparer CSVs, par exemple) utilise simplement

grep -F -x -f file1 file2 

ou la version fgrep simplifiée

fgrep -xf file1 file2 

De plus, vous pouvez utiliser file2* pour glob et rechercher des lignes communes à plusieurs fichiers, plutôt que seulement deux.

D'autres variations pratiques comprennent

  • -n drapeau pour afficher le numéro de ligne de chaque ligne associée
  • -c seulement compter le nombre de lignes qui correspondent à
  • -v pour afficher uniquement les lignes en file2 qui diffèrent (ou utilisent diff).

L'utilisation de comm est plus rapide, mais cette rapidité se fait au détriment du tri des fichiers. Ce n'est pas très utile en tant que «reverse diff».

+0

merci Ryder, cela pourrait plus utile que comm à beaucoup. Vous devriez lier à la réponse de la source (il y a plus d'une demi-douzaine de liens dans Q dans la navigation de droite, c'est un peu de travail à trouver). Il serait également intéressant de savoir si grep fonctionne bien avec une entrée non triée ou différemment, et peut imprimer les numéros de ligne respectifs des correspondances. –

+0

@mattwilkie - fait! – Ryder

+1

@mattwilkie J'ai ressenti le besoin de revenir et de clarifier l'utilisation du drapeau '-v' après que je me suis glissé moi-même. Imaginons que vous ayez deux fichiers csv, file1 et file2, et qu'ils contiennent des lignes qui se chevauchent et qui ne se chevauchent pas. Si vous voulez tout et seulement les lignes qui ne se chevauchent pas, l'utilisation de 'fgrep -v file1 file2' ne retournera que les lignes qui ne se chevauchent pas dans file2, * et aucune des lignes supplémentaires qui ne se chevauchent pas dans file1 *. Cela peut sembler évident à certains, mais il est préférable d'énoncer une évidence plutôt qu'une interprétation erronée du risque. Dans ce cas particulier, le tri des fichiers et l'utilisation de 'comm' est toujours le meilleur choix. – Ryder

1

Pour information, je l'ai fait un petit outil pour Windows faire la même chose que « grep -F -x -f fichier1 fichier2 » (Comme je l'ai pas trouvé quoi que ce soit équivalent à cette commande sous Windows)

ici, il est: http://www.nerdzcore.com/?page=commonlines

L'utilisation est "CommonLines inputFile1 inputFile2 outputFile"

Le code source est également disponible (GPL)

5

façon de faire est plus facile:

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

Les fichiers ne doivent pas nécessairement être triés.

+0

Cela ne ressemble pas à la plupart des réponses ici, car il vous permet de reconstruire des modèles source. J'ai deux fichiers construits à partir de la même enveloppe, avec un texte différent inséré à quelques points. Cette réponse m'a permis de récupérer l'emballage. –

Questions connexes