Wie findet man die am häufigsten vorkommenden Dateien im Verzeichnis?

Wie findet man die am häufigsten vorkommenden Dateien im Verzeichnis?

Ich habe ein Verzeichnis mit vielen Bildern (mehr als 100.000). Viele davon sind Duplikate/identische Bilder, aber natürlich haben alle unterschiedliche Dateinamen. Ich muss die Bilder mit den meisten Duplikaten in diesem Verzeichnis finden. Beispielsweise hat file1.jpeg 120 Duplikate, file2.jpeg hat 90 Duplikate usw.

Ich dachte, ich würde mir den MD5-Wert jeder Datei holen und eine Art Sortierung durchführen, aber die Details sind mir nicht klar. Kann das mit einem Shell-Skript gemacht werden?

Um es klar zu sagen: Ich muss (noch) keine Duplikate entfernen, ich muss herausfinden, welche Dateien die meisten Kopien haben.

Ich verwende OS X, falls das hilft.

Antwort1

Wenn es sich bei den Dateien um exakte Duplikate handelt, shasum * | sortkann eine Nachbearbeitung der Ausgabe hilfreich sein. Speichern Sie die Ausgabe in einer Datei, da die Berechnung eine Weile dauern kann und Sie sie wahrscheinlich mehr als einmal benötigen:

shasum * | sort >/tmp/shasums

So können Sie beispielsweise die Verbreitung identischer Dateien anzeigen (nur mit Prüfsummen, nicht mit Dateinamen):

</tmp/shasums cut -d ' ' -f 1 | uniq -c

So können Sie sowohl die Dateinamen als auch die Anzahl der Duplikate anzeigen:

</tmp/shasums sed 's/ .*//' | uniq -c - | join -1 2 - /tmp/shasums | sort -k 2,1

Ohne GNU uniq kann ich zur ansprechenden Anzeige der Dateinamen nichts Besseres anbieten als das folgende Perl-Skript:

</tmp/shasums perl -lne '
    s/^([^ ]*?)  //; # set $1 to the checksum and $2 to the filename
    push @{$names{$1}}, $_; # dispatch file names by checksum
    END {
        # iterate through the checksums, sorted by repeat count
        foreach (sort {@$a <=> @$b} values %names) {
            # print the repeat count and the file names
            printf "%d %s\n", scalar(@$_), join(" ", @$_)
        }
    }'

Antwort2

Dies ist eine schnelle und einfache Pipeline, die Namen von Duplikaten zwischen Zeilen mit Bindestrichen druckt. Sie sucht nur im aktuellen Verzeichnis, aber Sie können sie findfür eine rekursive Suche verwenden.

md5sum *.jpeg | sort | awk '{if ($1 != prev) print "-----"; print $2; prev = $1}'

Beispielausgabe:

-----
unique1.jpeg
-----
dup1.jpeg
dup2.jpeg
dup3.jpeg
-----
same1.jpeg
same2.jpeg
-----
solo1.jpeg

verwandte Informationen