Сравнивая количество файлов (двоичное) - PullRequest
0 голосов
/ 19 октября 2011

Я хочу сравнить несколько файлов и выяснить, какие файлы одинаковые, но они не обязательно являются текстовыми файлами (поэтому, пожалуйста, не предлагайте diff)

Файлы могут быть в любом формате (например, двоичные файлы).

Я обнаружил, что могу запустить md5sum, чтобы найти хэш каждого файла, а затем сравнить его вручную, чтобы проверить, совпадают ли они. Но как я могу автоматизировать этот процесс?

PS: Я также обнаружил, что могу хранить md5sums в файле, используя

md5sum <file-names> | cat >md5sum.txt

но я застрял на том, как автоматизировать этот процесс.

Я бы предпочел, чтобы это было сделано с помощью скрипта (язык без бара).

1 Ответ

3 голосов
/ 19 октября 2011

Если вы можете использовать такие языки, как perl или python со встроенной поддержкой хэшей / словарей, это действительно просто.

Зацикливание имен файлов и сигнатур и создание хэша с md5sum в качестве ключа и списка файлов с этимmd5 в качестве значения.

Затем переберите содержимое хэша и покажите записи с более чем одним элементом.Это файлы, которые могут быть идентичными (вы не можете быть уверены в подходе, основанном на подписи).

Поскольку люди просят код, может быть что-то вроде ниже.Это реализация Perl.Я могу добавить эквивалентный пример Python позже, если он понадобится.

#!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";
    }
}

Скажем, вы помещаете это в файл same.pl, вы называете его так:

perl same.pl

пример использования:

$ md5sum F*
c9904273735f3141c1dd61533e02246a  F1
c9904273735f3141c1dd61533e02246a  F2
c9904273735f3141c1dd61533e02246a  F3
d41d8cd98f00b204e9800998ecf8427e  F4

$ perl same.pl F1 F2 F3 F4
Files with same MD5 : F1-F2-F3

Ниже приведена возможная версия Python (работа с python2 и 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])))

Обратите внимание, что есливы сравниваете действительно большое количество файлов, предоставляя имена файлов в командной строке, как в приведенных выше примерах, может быть недостаточно, и вы должны использовать более сложный способ сделать это (или поместить какой-то глобус в скрипт) или командную строку оболочкипереполнится.

...