
Ich muss alle Dateien finden, die irgendwo in vorhanden sind dir1
, aber nirgendwo in vorhanden sind dir2
. dir1
und dir2
möglicherweise eine andere Struktur haben, sodass diff -r
es nicht gut funktioniert.
Antwort1
Versuchen Sie, eine Liste von Dateien ohne Pfad zu erstellen. Auf diese Weise können Sie zwei Verzeichnisse vergleichen. Die Dateinamen sollten jedoch alle unterschiedlich sein. Wenn derselbe Dateiname in dir1 in verschiedenen Unterverzeichnissen wiederholt vorkommt, wird durch das Entfernen des Pfads die Eindeutigkeit des Dateinamens aufgehoben. Sie können eine Liste aller Verzeichnisse ohne Pfadnamen wie folgt erhalten:
find dir1/ -exec basename {} \; | sort
find dir2/ -exec basename {} \; | sort
Alles zusammen würde ungefähr so aussehen
diff <(find dir1/ -exec basename {} \; | sort) <(find dir2/ -exec basename {} \; | sort)
Ich sehe, dass es einen Kommentar gibt, der die Verwendung von fdupes vorschlägt. fdupes
Das ist definitiv die bessere Lösung.
Antwort2
Eine einfache Methode wäre die Verwendung von md5sum
. Beachten Sie nur, dass Dateien mit der Länge Null immer als Duplikate angesehen werden. Sie sollten daher find
nur Dateien mit einer Größe von mindestens einem Byte verwenden.
find /first/path -type f -exec md5sum -b \{\} \; > /tmp/md5-path1.txt
cut -b1-32 < /tmp/md5-path1-short.txt
find /second/path -type f -exec md5sum -b \{\} \; > /tmp/md5-path2.txt
cut -b1-32 < /tmp/md5-path2-short.txt
Dateien in Pfad1, die nicht in Pfad2 sind (entfernen Sie die Option '-v'
grep /tmp/md5-path1.txt -v -F -f /tmp/md5/path2-short.txt
CYA-Stufe: professionell
Die oben angegebene Zahl 32 liegt daran, dass MD5-Hashes 32 Byte lang sind. Wenn Sie beispielsweise verwenden würden sha1sum
, bei dem die Wahrscheinlichkeit von Kollisionen noch geringer ist, würden Sie eine Länge von 40 verwenden; sha224sum
erfordert 56, sha256sum
erfordert 64 und sha512sum
128.
CYA-Level: paranoid
Dies funktioniert möglicherweise nicht in einigen Caching-Schemata, in denen Metadaten in Dateien gespeichert werdenderen Name den Hash der Originaldatei enthält.
(das ist mir tatsächlich vor Jahren bei einer Wordpress + Magento-Installation passiert, bei der wir einen riesigen Artikel-Cache migrieren und dabei veraltete Einträge entfernen wollten).
In diesem Fall müssten Sie ein anderes Hash-Schema verwenden (Quick Fix), um grep
die Rückgabe falscher Positivergebnisse oder die Verwechslung des Metadateneintrags mit der Originaldatei zu vermeiden (verwenden Sie also SHA1, wenn der Cache MD5 verwendet oder umgekehrt). Alternativ können Sie sed
alle Zeilen in den „kurzen“ Dateien umschreiben und am Anfang ein „^“ hinzufügen, um sie so in einen verankerten regulären Ausdruck umzuwandeln, und das -F
Flag entfernen grep
, um die Datei als reguläre Ausdrücke statt als einfache Zeichenfolgen zu verarbeiten.
Antwort3
Die Teillösung, die ich gefunden habe, ist:
find dir1 -type f | grep -vxFf <(fdupes -r dir1 dir2)
aber ich sage „teilweise“, weil, wenn es Duplikate in gibt dir1
, diese nicht angezeigt werden, also müssen Sie sie fdupes -r dir1
zuerst ausführen.