Ich versuche eine Möglichkeit zu finden, in einem bestimmten Verzeichnis nach doppelten Dateien (auch mit unterschiedlichen Namen) zu suchen und diese durch Symlinks zu ersetzen, die auf das erste Vorkommen verweisen. Ich habe es mit versucht, fdupes
aber es listet nur diese Duplikate auf.
Das ist der Kontext: Ich passe ein Symbolthema nach meinen Wünschen an, und ich habe festgestellt, dass viele Symbole, auch wenn sie unterschiedliche Namen und unterschiedliche Speicherorte in ihrem übergeordneten Ordner haben und für unterschiedliche Zwecke verwendet werden, im Grunde gleich sind Bild. Da es überflüssig ist, dieselbe Änderung zwanzig- oder dreissigmal anzuwenden, wenn nur eine wirklich notwendig ist, möchte ich nur ein Bild behalten und alle anderen verknüpfen.
Wenn ich beispielsweise fdupes -r ./
in dem Verzeichnis ausgeführt werde testdir
, werden möglicherweise die folgenden Ergebnisse zurückgegeben:
./file1.png
./file2.png
./subdir1/anotherfile.png
./subdir1/subdir2/yetanotherfile.png
Angesichts dieser Ausgabe möchte ich nur die Datei behalten file1.png
, alle anderen löschen und durch darauf verweisende Symlinks ersetzen, wobei alle ursprünglichen Dateinamen beibehalten werden. So file2.png
bleibt der Name erhalten, wird aber zu einem Link, file1.png
anstatt ein Duplikat zu sein.
Diese Links sollten nicht auf einen absoluten Pfad verweisen, sondern relativ zum übergeordneten testdir
Verzeichnis sein. dh yetanotherfile.png
wird zeigen auf ../../file1.png
, nicht auf/home/testuser/.icons/testdir/file1.png
Ich interessiere mich sowohl für Lösungen, die eine GUI und CLI beinhalten. Es ist nicht zwingend verwenden fdupes
ich es genannt habe , weil es ein Werkzeug ist , dass ich weiß, aber ich bin offen für Lösungen , die anderen Werkzeuge auch nutzen.
Ich bin mir ziemlich sicher, dass ein Bash-Skript für all das nicht so schwer zu erstellen sein sollte, aber ich bin nicht sachkundig genug, um herauszufinden, wie man es selbst schreibt.
quelle
v1.51
(Ubuntu 14.04.2 LTS).jdupes
unter github.com/jbruchon/jdupes hat die-L
Option, das gewünschte Hardlinking von Duplikatsätzen durchzuführen.${line//…/}
funktionierte der Teil nicht für mich, so dass ich einen saubereren Weg ging, um die erste "Master" -Datei auf Hardlink zu bringen.rsync
ein anderes Dateisystem verwenden? Oder wenn das Dateisystem die Hierarchie nicht beibehält, z. B. ein Sicherungsserver, der alles unterbringt/«machine-name»/...
? Oder wenn Sie aus dem Backup wiederherstellen möchten? Ich kann nicht sehen, wie Hardlinks hier erhalten bleiben. Relative Softlinks hätten wahrscheinlich eine bessere Überlebenschance.Wenn Sie nicht viel an Skripten interessiert sind, kann ich rdfind empfehlen . Damit werden die angegebenen Verzeichnisse nach doppelten Dateien durchsucht und entweder per Hard- oder Softlink miteinander verknüpft. Ich habe es zum Deduplizieren meines Ruby-Edelsteinverzeichnisses mit großem Erfolg verwendet. Es ist in Debian / Ubuntu verfügbar.
quelle
Ich hatte eine ähnliche Situation, aber in meinem Fall sollte der symbolische Link auf einen relativen Pfad verweisen, also habe ich dieses Python-Skript geschrieben , um den Trick auszuführen:
Für jede Eingabezeile (die eine Liste von Dateien ist) teilt das Skript die Dateiliste (durch Leerzeichen getrennt), ruft den relativen Pfad von jeder Datei zur ersten ab und erstellt dann den Symlink.
quelle
Die Antwort von arnefm (die über das Internet kopiert wurde) behandelt also keine Leerzeichen in Dateinamen. Ich habe ein Skript geschrieben, das sich mit Leerzeichen in Dateien befasst.
Was dies bedeutet, ist Dupes zu finden und sie PIPE getrennt in eine Datei mit dem Namen "files" zu schreiben.
Anschließend wird die Datei zeilenweise in ein Array zurückgelesen, und jedes Element des Arrays wird durch die PIPE begrenzt.
Anschließend werden alle nicht ersten Elemente des Arrays durchlaufen, wobei die Datei durch einen Symlink zum ersten Element ersetzt wird.
Die externe Datei ('files') könnte entfernt werden, wenn der Befehl fdupes in einer Subshell ausgeführt wird, die von der Zeit direkt gelesen wird, aber dieser Weg scheint klarer zu sein.
quelle
Einige Vorbehalte vorab:
fdupes -1r common/base/dir | while read -r -a line ; do ln -sf $(realpath --relative-to ${line[1]} ${line[0]}) ${line[1]}; done
Wenn mehr als 2 Dateien Duplikate sind (z. B. Datei1 Datei2 Datei3), müssen wir für jedes Paar einen Symlink erstellen. Behandeln Sie Datei1, Datei2 und Datei1, Datei3 als zwei separate Fälle:
Wenn Sie dies tun, um automatisch eine beliebige Anzahl von Duplikaten pro Zeile zu verarbeiten, ist der Aufwand etwas höher.
Ein anderer Ansatz wäre, zuerst Symlinks zu absoluten Pfaden zu erstellen und diese dann zu konvertieren:
Dies basiert auf der Antwort von @Gilles: /unix//a/100955/77319
quelle