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".
6 réponses
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}
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ù.
Une alternative moins efficace (que comm):
cat <(ls 1 | sort -u) <(ls 2 | sort -u) | uniq -d
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)
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.