Intersection de deux listes dans Bash

J'essaie d'écrire un script simple qui listera le contenu trouvé dans deux listes. Pour simplifier, utilisons ls comme exemple. Imaginez "un" et "deux" sont des répertoires.

one=`ls one`
two=`ls two`
intersection $one $two

Je suis toujours assez vert en bash, alors n'hésitez pas à corriger comment je fais cela. J'ai juste besoin d'une commande qui imprimera tous les fichiers dans " un " et "deux". Ils doivent exister dans les deux. Vous pouvez appeler cela "l'intersection" entre " un " et "deux".

129
demandé sur User1 2010-04-23 07:37:14

6 réponses

comm -12  <(ls 1) <(ls 2)
209
répondu ghostdog74 2010-04-23 03:58:01

Solution avec comm

comm est génial mais en effet besoin de travailler avec la liste triée. Et heureusement ici nous utilisons {[6] } qui à partir de ls Bash man page

Trier les entrées par ordre alphabétique si aucun des-cftuSUX ni --sort.

comm -12  <(ls one) <(ls two)

Alternative avec sort

Intersection de deux listes:

sort <(ls one) <(ls two) | uniq -d

Différence Symétrique de deux listes:

sort <(ls one) <(ls two) | uniq -u

Bonus

Jouez avec;)

cd $(mktemp -d) && mkdir {one,two} && touch {one,two}/file_{1,2}{0..9} && touch two/file_3{0..9}
33
répondu Jean-Christophe Meillaud 2017-06-13 18:52:33

Utilisez la commande comm:

ls one | sort > /tmp/one_list
ls two | sort > /tmp/two_list
comm -12 /tmp/one_list /tmp/two_list

"sort" n'est pas vraiment nécessaire mais je l'inclus toujours avant d'utiliser "comm" juste au cas où.

28
répondu DVK 2012-05-30 01:50:02

Une alternative moins efficace (que comm):

cat <(ls 1 | sort -u) <(ls 2 | sort -u) | uniq -d
2
répondu Benubird 2013-05-17 09:20:14

Jointure est une autre bonne option en fonction de l'entrée et de la sortie souhaitée

join -j1 -a1 <(ls 1) <(ls 2)
2
répondu frogstarr78 2014-04-10 01:29:08

Il y a une autre question Stackoverflow "intersection de tableau dans bash", qui est marquée comme un doublon de ceci. Ce n'est pas tout à fait la même chose, à mon avis, car cette question parle de comparer deux tableaux bash, alors que cette question se concentre sur les fichiers bash. Une réponse d'une ligne à l'autre question, qui est maintenant fermée, est la suivante:

# List1=( 0 1 2 3 4   6 7 8 9 10 11 12)
# List2=(   1 2 3   5 6   8 9    11 )
# List3=($(comm -12 <(echo ${List1[*]}| tr " " "\n"| sort) <(echo ${List2[*]} | tr " " "\n"| sort)| sort -g))
# echo ${List3[*]}
1 2 3 6 8 9 11

L'utilitaire comm effectue un tri alphanumérique, alors que les réponses "array intersection in bash" utilisent des nombres; d'où les "sort" et " sort-g" utilisation.

-2
répondu Chuck Newman 2017-04-18 18:25:17