En comparant un nombre n de fichiers (binaire)
-
27-10-2019 - |
Question
Je veux comparer un certain nombre de fichiers et savoir quels sont les fichiers qui sont les mêmes, mais ils ne sont pas nécessairement des fichiers texte (donc s'il vous plaît ne pas suggérer diff
)
Les fichiers peuvent être dans tous les formats (c.-à-fichiers binaires).
Je trouve que je peux courir md5sum
pour trouver le hachage de chaque fichier, puis le comparer manuellement pour vérifier si elles sont les mêmes. Mais comment puis-je automatiser ce processus?
Ps: Je trouve aussi que je peux stocker les md5sums dans un fichier en utilisant
md5sum <file-names> | cat >md5sum.txt
mais je suis coincé sur la façon d'automatiser ce processus.
Je préférerais que cela soit fait par un script (langue non-bar).
La solution
Si vous pouvez utiliser des langages comme perl ou python avec support pour builtin hashes / dictionnaires, il est vraiment facile.
Boucle sur les noms de fichiers et la signature et de créer un hachage avec md5sum comme la clé et la liste des fichiers avec cette md5 en tant que valeur.
Ensuite, la boucle sur le contenu des entrées de hachage et de montrer avec plus d'un élément. Ces fichiers sont susceptibles d'être identiques (vous ne pouvez pas être vraiment sûr avec une approche basée sur la signature).
Comme les gens demandent code, peut-être quelque chose comme ci-dessous. C'est une implémentation de Perl. Je peux ajouter un échantillon équivalent python plus tard si on le veut.
#!perl
my $same = {};
for my $x (@ARGV){
my ($sig, $name) = split(/\s+/, `md5sum $x`);
if (!defined($same{$sig})){$same{$sig} = []}
push @{$same{$sig}}, $name;
}
for my $sig (keys %same){
if (@{$same{$sig}} > 1){
print "Files with same MD5 : ".join('-', @{$same{$sig}})."\n";
}
}
Dites que vous avez mis que dans un same.pl de fichier, vous l'appelez comme:
perl same.pl
d'utilisation exemple:
$ md5sum F*
c9904273735f3141c1dd61533e02246a F1
c9904273735f3141c1dd61533e02246a F2
c9904273735f3141c1dd61533e02246a F3
d41d8cd98f00b204e9800998ecf8427e F4
$ perl same.pl F1 F2 F3 F4
Files with same MD5 : F1-F2-F3
Voici une version python possible (en collaboration avec les deux python2 et python3).
#!python
import hashlib
def md5sum(filename):
f = open(filename, mode='rb')
buf = f.read(128)
d = hashlib.md5(buf)
while len(buf) == 128:
buf = f.read(128)
d.update(buf)
return d.hexdigest()
if __name__ == "__main__":
import sys
same = {}
for name in sys.argv[1:]:
sig = md5sum(name)
same.setdefault(sig, []).append(name)
for k in same:
if len(same[k]) > 1:
print("Files with same MD5: {l}".format(l="-".join(same[k])))
Notez que si vous comparez nombre vraiment grand nombre de fichiers, fournissant les noms de fichiers en ligne de commande comme dans les exemples ci-dessus ne peut être suffisant et vous devez utiliser une certaine façon plus élaborée pour le faire (ou mettre un peu glob dans le script) ou la ligne de commande shell va déborder.