比较n个文件(二进制)

时间:2011-10-19 13:13:36

标签: linux scripting hash md5 file-comparison

我想比较一些文件,找出哪些文件是相同的,但它们不一定是文本文件(所以请不要建议diff

文件可以是任何格式(即二进制文件)。

我发现我可以运行md5sum来查找每个文件的哈希值,然后手动比较它以检查它们是否相同。但是我该如何自动化这个过程呢?

Ps:我还发现我可以使用

将md5sums存储在一个文件中
md5sum <file-names> | cat >md5sum.txt

但我仍然坚持如何自动化这个过程。

我希望通过脚本(语言无栏)来完成。

1 个答案:

答案 0 :(得分:3)

如果你可以使用像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])))

请注意,如果您要比较非常多的文件,在上面的示例中提供命令行上的文件名可能是不够的,您应该使用一些更复杂的方法来执行此操作(或在脚本中放置一些glob) ,或shell命令行将溢出。