198 votes

Comparaison du contenu de deux répertoires

J'ai deux répertoires qui devraient contenir les mêmes fichiers et avoir la même structure de répertoire.

Je pense qu'il manque quelque chose dans l'un de ces répertoires.

En utilisant le bash Shell, y a-t-il un moyen de comparer mes répertoires et de voir si l'un d'eux manque de fichiers qui sont présents dans l'autre ?

173voto

Alex R. Points 2027

Vous pouvez utiliser le diff comme vous le feriez pour des fichiers :

diff <directory1> <directory2>

Si vous voulez aussi voir les sous-dossiers et les -fichiers, vous pouvez utiliser l'option -r option :

diff -r <directory1> <directory2>

141voto

Adail Junior Points 1606

Une bonne façon de faire cette comparaison est d'utiliser find con md5sum alors a diff .

Exemple

Utilisez find pour lister tous les fichiers dans le répertoire, puis calculez le hachage md5 pour chaque fichier et envoyez-le trié par nom de fichier dans un fichier :

find /dir1/ -type f -exec md5sum {} + | sort -k 2 > dir1.txt

Faites la même procédure pour l'autre répertoire :

find /dir2/ -type f -exec md5sum {} + | sort -k 2 > dir2.txt

Comparez ensuite les deux fichiers obtenus avec diff :

diff -u dir1.txt dir2.txt

Ou comme une commande unique utilisant la substitution de processus :

diff <(find /dir1/ -type f -exec md5sum {} + | sort -k 2) <(find /dir2/ -type f -exec md5sum {} + | sort -k 2)

Si vous voulez voir seulement les changements :

diff <(find /dir1/ -type f -exec md5sum {} + | sort -k 2 | cut -f1 -d" ") <(find /dir2/ -type f -exec md5sum {} + | sort -k 2 | cut -f1 -d" ")

La commande cut n'imprime que le hash (premier champ) à comparer par diff. Sinon, diff imprimera chaque ligne, car les chemins des répertoires diffèrent même si le hachage est le même.

Mais vous ne saurez pas quel fichier a changé...

Pour cela, vous pouvez essayer quelque chose comme

diff <(find /dir1/ -type f -exec md5sum {} + | sort -k 2 | sed 's/ .*\// /') <(find /dir2/ -type f -exec md5sum {} + | sort -k 2 | sed 's/ .*\// /')

Cette stratégie est très utile lorsque les deux répertoires à comparer ne se trouvent pas sur la même machine et que vous devez vous assurer que les fichiers sont identiques dans les deux répertoires.

Une autre bonne façon de faire le travail est d'utiliser la méthode de Git. diff (peut causer des problèmes lorsque les fichiers ont des permissions différentes -> chaque fichier est alors listé dans la sortie) :

git diff --no-index dir1/ dir2/

59voto

Braiam Points 64282

Si vous n'utilisez pas bash, vous pouvez le faire en utilisant diff avec --brief y --recursive :

$ diff -rq dir1 dir2 
Only in dir2: file2
Only in dir1: file1

Le site man diff comprend les deux options :

-q , --brief
rapport uniquement lorsque les fichiers diffèrent

-r , --recursive
comparer récursivement tous les sous-répertoires trouvés

23voto

Ferroao Points 521

Peut-être qu'une option est d'exécuter rsync deux fois :

rsync -rtOvcs --progress -n /dir1/ /dir2/

Avec la ligne précédente, vous obtiendrez des fichiers qui sont dans le répertoire 1 et qui sont différents (ou manquants) dans le répertoire 2.

rsync -rtOvcs --progress -n /dir2/ /dir1/

De même pour dir2

#from the rsync --help :
-n, --dry-run               perform a trial run with no changes made

-r, --recursive             recurse into directories
-t, --times                 preserve modification times
-O, --omit-dir-times        omit directories from --times
-v, --verbose               increase verbosity
    --progress              show progress during transfer
-c, --checksum              skip based on checksum, not mod-time & size
-s, --protect-args          no space-splitting; only wildcard special-chars

Vous pouvez supprimer le -n option pour subir les changements. C'est-à-dire copier la liste des fichiers dans le deuxième dossier.

Si c'est le cas, une bonne option est d'utiliser -u pour éviter d'écraser les fichiers les plus récents.

-u, --update                skip files that are newer on the receiver

Une seule phrase :

rsync -rtOvcsu --progress -n  /dir1/ /dir2/ && rsync -rtOvcsu --progress -n /dir2/ /dir1/

16voto

joeytwiddle Points 1759

Voici une alternative, pour comparer uniquement les noms de fichiers, et non leur contenu :

diff <(cd folder1 && find . | sort) <(cd folder2 && find . | sort)

Il s'agit d'une façon simple de lister les fichiers manquants, mais bien sûr cela ne détectera pas des fichiers ayant le même nom mais des contenus différents !

(Personnellement, j'utilise mon propre diffdirs script, mais qui fait partie d'une plus grande bibliothèque .)

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X