Extraire les fichiers identiques de deux répertoires

0

Je cherche une solution linux pour le problème suivant:

Étant donné deux répertoires avec un grand nombre de fichiers. Tous les noms de fichiers sont aléatoires et différents dans les deux répertoires. Le contenu de certains des fichiers des deux répertoires est toutefois identique.

Je veux copier tous les fichiers présents dans les deux répertoires dans un troisième. ("Se produire dans les deux" signifie avoir le même contenu, pas le même nom.)

Mel
la source

Réponses:

1

En supposant que vos noms de fichiers ne comportent aucun espace et qu'il n'y ait aucun sous-répertoire dans l'un ou l'autre de ces répertoires, les éléments suivants imprimeront des paires de noms de fichiers avec des sommes MD5 correspondantes:

join -o 1.2,2.2 <(md5sum $D1/* | sort) <(md5sum $D2/* | sort)

Pour obtenir un seul nom de fichier, utilisez -o 1.2ou -o 2.2.

Si les noms de fichiers (ou chemins) peuvent inclure des espaces, vous devrez être plus intelligent.

Si un seul répertoire peut avoir le même fichier avec plusieurs noms, vous devrez également faire preuve de plus d'intelligence - et décider de la marche à suivre. Une possibilité serait de filtrer les doublons avant de faire la jointure:

join -o 1.2,2.2 <(md5sum $D1/* | sort | uniq -w16) \
                <(md5sum $D2/* | sort | uniq -w16)

NE PAS UTILISER sum

sumgénère une somme de contrôle de 16 bits; si vous avez même quelques centaines de fichiers dans chaque répertoire, il est probable que vous obtiendrez un faux positif si vous comparez des sommes de contrôle 16 bits. md5sumn’est pas non plus absolument sans danger, mais les probabilités d’une collision avec des sommes de contrôle de 128 bits sont infimes. En cas de doute, et si c'est vraiment important, cmples fichiers aussi:

join -o 1.2,2.2 <(md5sum $D1/* | sort) <(md5sum $D2/* | sort) |
while read F1 F2; do
  if cmp -s $F1 $F2; then
    cp F1 $D3
  fi
done

(Encore une fois, cela ne fonctionnera pas si les noms des fichiers peuvent avoir des espaces.)

rici
la source
0

En utilisant votre shell préféré pour ce pseudo-code:

cd D1; sum * | while read l; do echo "D1 $l"; done >/tmp/foo
cd D2; sum * | while read l; do echo "D2 $1"; done >>/tmp/foo

sort -n /tmp/foo | awk '
$1 == prev_cs { echo "cp $3 dest"}
     /prev_cs = $1/
' | shell

Vous pouvez sauvegarder la sortie awk pour la réviser avant d’en produire les copies, si vous le souhaitez.

mpez0
la source
sumC'est vraiment une mauvaise idée, voir en.wikipedia.org/wiki/Birthday_problem . Si vous avez 300 fichiers aléatoires différents, les chances sont à peu près égales que deux d'entre eux aient la même chose sum.
rici
Ensuite, choisissez un algorithme de somme de contrôle différent, comme openssl dgst -md5. Même code.
mpez0
0

Cela pourrait faire l'affaire, comme avec mpez0's et copier les dups.

find {tst1,tst2} -exec sum {} {} \; 2> /dev/null | sort | uniq

Amos Folarin
la source