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 ?

9voto

Leos313 Points 1542

Je voudrais vous proposer un outil formidable que je viens de découvrir : MELD .

Il fonctionne correctement et tout ce que vous pouvez faire avec la commande diff sur un système basé sur Linux, peut y être reproduit avec une belle interface graphique !

Par exemple, le comparaison des répertoires est simple :

directories comparison

et aussi le comparaison de fichiers est facilitée :

files comparison

Il y a une belle intégration avec certaines versions de contrôle (par exemple Git) et peut être utilisé comme outil de fusion . Voir la documentation complète sur son site web.

5voto

joeytwiddle Points 1759

Si vous voulez que chaque fichier soit extensible et rétractable, vous pouvez faire passer la sortie de la commande diff -r dans Vim.

D'abord, donnons à Vim une règle de pliage :

mkdir -p ~/.vim/ftplugin
echo "set foldexpr=getline(v:lnum)=~'^diff.*'?'>1':1 foldmethod=expr fdc=2" >> ~/.vim/ftplugin/diff.vim

Maintenant juste :

diff -r dir1 dir2 | vim - -R

Vous pouvez frapper zo y zc pour ouvrir et fermer les plis. Pour sortir de Vim, tapez :q<Enter>

Le site -R est facultatif, mais je le trouve utile à côté de - parce que cela empêche Vim de vous demander de sauvegarder le tampon lorsque vous quittez.

5voto

Andriy Makukha Points 151

Inspiré par la réponse de Sergiy, j'ai écrit mon propre Python script pour comparer deux répertoires.

Contrairement à de nombreuses autres solutions, il ne compare pas le contenu des fichiers. De même, il ne va pas à l'intérieur des sous-répertoires qui sont manquants dans l'un des répertoires. Ainsi, la sortie est assez concise et le script fonctionne rapidement avec de grands répertoires.

#!/usr/bin/env python3

import os, sys

def compare_dirs(d1: "old directory name", d2: "new directory name"):
    def print_local(a, msg):
        print('DIR ' if a[2] else 'FILE', a[1], msg)
    # ensure validity
    for d in [d1,d2]:
        if not os.path.isdir(d):
            raise ValueError("not a directory: " + d)
    # get relative path
    l1 = [(x,os.path.join(d1,x)) for x in os.listdir(d1)]
    l2 = [(x,os.path.join(d2,x)) for x in os.listdir(d2)]
    # determine type: directory or file?
    l1 = sorted([(x,y,os.path.isdir(y)) for x,y in l1])
    l2 = sorted([(x,y,os.path.isdir(y)) for x,y in l2])
    i1 = i2 = 0
    common_dirs = []
    while i1<len(l1) and i2<len(l2):
        if l1[i1][0] == l2[i2][0]:      # same name
            if l1[i1][2] == l2[i2][2]:  # same type
                if l1[i1][2]:           # remember this folder for recursion
                    common_dirs.append((l1[i1][1], l2[i2][1]))
            else:
                print_local(l1[i1],'type changed')
            i1 += 1
            i2 += 1
        elif l1[i1][0]<l2[i2][0]:
            print_local(l1[i1],'removed')
            i1 += 1
        elif l1[i1][0]>l2[i2][0]:
            print_local(l2[i2],'added')
            i2 += 1
    while i1<len(l1):
        print_local(l1[i1],'removed')
        i1 += 1
    while i2<len(l2):
        print_local(l2[i2],'added')
        i2 += 1
    # compare subfolders recursively
    for sd1,sd2 in common_dirs:
        compare_dirs(sd1, sd2)

if __name__=="__main__":
    compare_dirs(sys.argv[1], sys.argv[2])

Si vous l'enregistrez dans un fichier nommé compare_dirs.py vous pouvez l'exécuter avec Python3.x :

python3 compare_dirs.py dir1 dir2

Exemple de sortie :

user@laptop:~$ python3 compare_dirs.py old/ new/
DIR  old/out/flavor-domino removed
DIR  new/out/flavor-maxim2 added
DIR  old/target/vendor/flavor-domino removed
DIR  new/target/vendor/flavor-maxim2 added
FILE old/tmp/.kconfig-flavor_domino removed
FILE new/tmp/.kconfig-flavor_maxim2 added
DIR  new/tools/tools/LiveSuit_For_Linux64 added

P.S. Si vous avez besoin de comparer les tailles et les hachages de fichiers pour des changements potentiels, j'ai publié un script mis à jour ici : https://gist.github.com/amakukha/f489cbde2afd32817f8e866cf4abe779

4voto

Sergiy Kolodyazhnyy Points 97292

Une tâche assez facile à réaliser en Python :

python -c 'import os,sys;d1=os.listdir(sys.argv[1]);d2=os.listdir(sys.argv[2]);d1.sort();d2.sort();x="SAME" if d1 == d2 else "DIFF";print x' DIR1 DIR2

Remplacer les valeurs réelles par DIR1 et DIR2 .

Voici un exemple d'exécution :

$ python -c 'import os,sys;d1=os.listdir(sys.argv[1]);d2=os.listdir(sys.argv[2]);d1.sort();d2.sort();x="SAME" if d1 == d2 else "DIFF";print x' Desktop/ Desktop
SAME
$ python -c 'import os,sys;d1=os.listdir(sys.argv[1]);d2=os.listdir(sys.argv[2]);d1.sort();d2.sort();x="SAME" if d1 == d2 else "DIFF";print x' Desktop/ Pictures/
DIFF

Pour plus de lisibilité, voici un véritable script au lieu d'un one-liner :

#!/usr/bin/env python
import os, sys

d1 = os.listdir(sys.argv[1])
d2 = os.listdir(sys.argv[2])
d1.sort()
d2.sort()

if d1 == d2:
    print("SAME")
else:
    print("DIFF")

2voto

pebox11 Points 488

La bonne réponse d'Adail Junior pourrait avoir un problème de temps d'exécution si vous avez des centaines de milliers de fichiers ! Voici donc une autre façon de procéder. Disons que vous voulez comparer tous les noms de fichiers du dossier A avec tous les noms de fichiers du dossier B. Etape 1, allez dans le dossier A et faites :

find . | sort -k 2 > listA.txt

Etape 2, cd vers le dossier B et faire :

find . | sort -k 2 > listB.txt

Etape 3, prenez la différence entre listA.txt et listB.txt.

J'ai essayé cela dans des dossiers contenant un demi-million de fichiers txt et en moins de 30 secondes j'ai eu la différence sur mon écran, alors que le calcul des md5sums, puis le piping et enfin l'ajout peuvent prendre beaucoup de temps. Notez également que la question originale demande de comparer les noms de fichiers (pas leur contenu !) et de vérifier s'il manque des fichiers entre les dossiers comparés ! Merci

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