Domanda

voglio mettere a confronto una serie di file e scoprire quali file che sono gli stessi, ma non sono necessariamente i file di testo (Quindi, per favore non suggeriscono diff)

I file possono essere in qualsiasi formato (ad esempio file binari).

ho scoperto che posso correre md5sum per trovare l'hash di ogni file e quindi confrontare manualmente per verificare se sono la stessa cosa. Ma come posso automatizzare questo processo?

Ps: Ho anche scoperto che posso memorizzare i md5sums in un file utilizzando

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

, ma io sono bloccato su come automatizzare questo processo.

preferirei questo per essere fatto tramite uno script (linguaggio non-bar).

È stato utile?

Soluzione

Se è possibile utilizzare linguaggi come Perl o Python con supporto integrato per gli hash / dictionnaries, è davvero facile.

Loop su nomi di file e firma e creare un hash con md5sum come chiave e la lista dei file con quel MD5 come valore.

Poi ciclo sul contenuto delle voci di hash e spettacolo con più di un elemento. Questi file sono suscettibili di essere identici (non si può essere veramente sicuro che con un approccio basato su firma).

Dato che le persone chiedono codice, forse qualcosa di simile qui di seguito. Questa è un'implementazione perl. Posso aggiungere un campione di pitone equivalente in seguito, se si vuole.

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

Di che hai messo che in un file same.pl, si chiama come:

perl same.pl

esempio di utilizzo:

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

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

Di seguito è riportato una possibile versione di Python (che lavora sia con python2 e 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])))

Si noti che se si confrontano davvero gran numero di file, fornendo i nomi di file sulla linea di comando come negli esempi di cui sopra potrebbe non essere sufficiente e si dovrebbe usare un modo più elaborato per farlo (o mettere un po 'glob all'interno dello script) o la riga di comando traboccherà.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top