4 votes

Identifier les éléments communs dans plusieurs fichiers

J'ai 8 fichiers d'une colonne et un nombre non uniforme de lignes dans chaque colonne. J'ai besoin d'identifier les éléments qui sont communs à l'ensemble de ces 8 fichiers.

Je peux effectuer cette tâche pour comparer deux fichiers, mais je ne suis pas en mesure d'écrire une ligne de commande utilisable en shell pour faire la même chose.

Des idées ? .....

Merci d'avance.

Dossier 1
Paul
pawan

Dossier 2
Raman
Paul
doux
barua

Dossier 3
Sweet
barua
Paul

La réponse de la comparaison de ces trois fichiers devrait être Paul.

8voto

Fredrik Pihl Points 20944

La ligne suivante devrait faire l'affaire (modifiez 3 à 8 pour correspondre à votre cas)

$ sort * | uniq -c | grep 3
      3 Paul

Il est probablement préférable de le faire en python, en utilisant les éléments suivants sets ...

6voto

eumiro Points 56644
python -c 'import sys;print "".join(sorted(set.intersection(*[set(open(a).readlines()) for a in sys.argv[1:]])))' File1 File2 File3

imprime Paul pour vos fichiers File1 , File2 y File3 .

4voto

Zaid Points 21192

Perl

$ perl -lnE '$c{$_}{$ARGV}++ }{ print for grep { keys %{$c{$_}} == 8 } keys %c;' file[1-8]

Il devrait être possible de se débarrasser du code dur 8 également avec @{[ glob "@ARGV" ]} mais je n'ai pas le temps de le tester maintenant.

Cette solution permet également de gérer correctement l'existence de lignes dupliquées dans les fichiers.

3voto

TLP Points 48922

J'ai essayé de trouver un moyen concis de m'assurer que chaque correspondance provient d'un fichier différent. S'il n'y a pas de doublons dans les fichiers, c'est assez simple en perl :

perl -lnwE '$a{$_}++; END { for (keys %a) { print if $a{$_} == 3 } }' files*

El -l permettra de décomposer automatiquement votre entrée (supprimer la nouvelle ligne), et ajoutera une nouvelle ligne à l'impression. Ceci est important dans le cas où il manque eof newlines.

El -n l'option lira l'entrée depuis les arguments du nom de fichier (ou stdin).

L'affectation de hachage comptera les doublons, et le bloc END imprimera les doublons apparus 3 fois. Remplacez 3 par le nombre de fichiers que vous avez.

Si vous souhaitez une version un peu plus souple, vous pouvez compter les arguments dans un bloc BEGIN.

perl -lnwE 'BEGIN { $n = scalar @ARGV } 
    $a{$_}++; END { for (keys %a) { print if $a{$_} == $n } }' files*

2voto

kev Points 41855
$ awk '++a[$0]==3' file{1..3}.txt
Paul

mise à jour

$ awk '(FILENAME SEP $0) in b{next}; b[FILENAME,$0]=1 && ++a[$0]==3' file{1..3}.txt
Paul

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X