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 * | sort
kann 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 find
fü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