So fügen Sie doppelte Ordner mit der Struktur "Name (1)", "Name (1) (1)" usw. zusammen

575
Josh

Die Synchronisierung zwischen meinem Google Filestream, Google Drive und Synology CloudSync hat alles durcheinander gebracht und ich habe hunderte von doppelten Ordnern mit dem Ordnernamen, gefolgt von einem "(1)" oder "(2)" usw., übrig bis "(1) (1) (1)".

Kennen Sie ein Programm oder ein Skript, das diese Ordner zusammenführen kann?

Beispiel Ordnerstruktur auf oberster Ebene:

1100 Beetledwarf - Happy ATE 1100 Beetledwarf - Happy ATE (1) 1100 Beetledwarf - Happy ATE (2) 1100 Beetledwarf - Happy ATE (3) 1100 Beetledwarf - Happy ATE (3) (1) 1100 Beetledwarf - Happy ATE (3) (1) (1) 1100 Beetledwarf - Happy ATE (4) 1100 Beetledwarf - Happy ATE (5) 1100 Beetledwarf - Happy ATE (6) 

Da Unterordner manchmal dasselbe Problem haben, müsste das Programm oder Skript Ordner mit diesem Benennungsmuster für alle Unterordner zusammenführen können. Beispiel:

Beispiel Ordner der zweiten Ebene:

1100 Beetledwarf - Happy ATE (6) Analysis Analysis (1) Smirckle_HL Smirckle_HL (2) Pending Reports Photos & Logos 

Die beste Lösung würde es mir auch ermöglichen, Dateien zu verschieben, anstatt sie zu kopieren, da das Kopieren von Dateien sehr lange dauert, das Verschieben jedoch fast sofort erfolgt.

Liste der Dinge, die ich bereits ausprobiert habe, aber keine von ihnen kann sich mit der Ordnerstruktur "Name (1)" beschäftigen (was ich bisher feststellen kann), und alle kopieren Dateien, anstatt sie zu verschieben:

  • WinMerge für Windows 10 <- Chokes beim Kopieren von Google-Laufwerksdateien (gibt etwa "DOS-Befehl nicht unterstützt") zurück
  • Meld für MacOS. <- langsam
  • Terminal mit "ditto" -Befehl in OS X <- Beste Option bisher.

Danke für Ihre Hilfe!

1
Wenn ich Sie richtig verstanden habe, dauert das Verschieben von Dateien in Ihrem Fall über die Internetverbindung die gleiche Zeit wie das Kopieren. Sie verwechseln es mit dem Verschieben von Dateien * innerhalb * einer HD-Partition, das ist schnell. Das Verschieben zwischen Partitionen, zwischen HDs, zwischen PCs usw. dauert in der Regel erheblich länger (bei bestimmten Konfigurationen keine Ausnahme). Albin vor 5 Jahren 0
Danke, ich habe das Bit über meine Internetverbindung entfernt, weil es nicht so ist. Wenn Sie unter Windows und Mac OS einen Google-Dateistream verwenden, bewegen Sie Dateien beim Verschieben von Dateien wie innerhalb einer HD-Partition: Wenn Sie Dateien verschieben, ändert das Betriebssystem normalerweise nur die Zeiger, die auf die Datei verweisen, aber wenn Sie sie kopieren, dann kopiert das Betriebssystem die Daten normalerweise an einen neuen Ort auf dem Laufwerk. In diesem Fall dauert das Kopieren noch mehr Zeit, da die HD über das Internet angeschlossen wird. Prost! Josh vor 5 Jahren 0
Hallo. Ich arbeite an einem Pyhton-Skript, um speziell Ihre Frage zu lösen. Es ist einigermaßen fertig, aber ich kann bis zum Montag leider nicht mehr Zeit damit verbringen, die (wichtigen) Feinarbeiten (Schutzmaßnahmen) durchzuführen, = /, da ich auf Reisen bin. Wenn Sie auf eine Antwort davor stoßen, gut - ohnehin toll für Sie = D, aber wenn Sie keine finden, kann ich diese beenden und als Antwort hier posten =). Haben Sie einen guten Tag. Vinícius M vor 5 Jahren 0

2 Antworten auf die Frage

1
Kamil Maciorowski

Dies ist der Ansatz, den ich unter Linux versuchen würde. Ich habe keine Erfahrung mit Google Filestream, Google Drive oder Synology CloudSync. Daher kann ich nicht sagen, ob die Lösung überhaupt angewendet werden kann. Trotzdem hoffe ich, dass Ihnen das zumindest ein paar Ideen geben wird.


Annahmen

  • Sie können den Anteil in Ihrem Verzeichnisbaum montieren, so mv, cpund andere vernünftige Werkzeuge können mit Verzeichnissen wie funktionieren, wenn sie lokal;
  • Dateien (oder Verzeichnisse) mit Pfaden, die nach dem Entfernen aller (N)Zeichenfolgen identisch werden, sind in der Tat Instanzen derselben Datei (Verzeichnis).
  • Instanzen derselben Datei sollten nur eine Datei hinterlassen.
  • Instanzen desselben Verzeichnisses sollten ihren Inhalt in einem einzigen Verzeichnis zusammenführen.
  • Sie können alle Werkzeuge verwenden, die ich hier verwende.

Verfahren

Bitte lesen Sie die gesamte Antwort, bevor Sie versuchen, etwas zu tun.

Ich denke, dass einige Schritte als Skript geschrieben werden könnten, aber da die Lösung sehr experimentell ist, ist es besser, sie Schritt für Schritt von Hand zu machen und darauf zu achten, was passiert.

  1. In einer Shell cdzum Mountpoint und Aufruf find . | vidir -; Verwenden Sie einen Texteditor Ihrer Wahl, zB katewie folgt:

    find . | EDITOR=kate vidir 

    Dadurch wird der Editor mit einer Liste aller Objekte geöffnet, von denen jedes eine eigene Nummer hat. Wenn Sie den Inhalt ändern und die (temporäre) Datei speichern und den Editor schließen, werden alle Änderungen übernommen. Im Allgemeinen können Sie Folgendes tun:

    • Pfade ändern, um Dateien oder Verzeichnisse zu verschieben (umzubenennen);
    • Zeilen löschen, um Dateien oder Verzeichnisse zu entfernen;
    • Tauschen Sie zwei oder mehr Zahlen aus, um Dateien auszutauschen (Sie werden es nicht brauchen).

    Speichern Sie die Datei nur, wenn Sie sicher sind, dass der neue Inhalt die gewünschte Verzeichnisstruktur beschreibt.

  2. Kopieren Sie den Inhalt aus dem Editor in eine andere Datei. Es geht darum, damit zu arbeiten und das Ergebnis erst dann wieder einzufügen (und zu speichern), wenn Sie sicher sind, dass Sie es richtig verstanden haben. Die nächsten Schritte beziehen sich auf die neue Datei, sofern nicht ausdrücklich etwas anderes angegeben ist.

  3. Verwenden Sie sedoder ein anderes Werkzeug, um alle (N)Zeichenketten zu entfernen (beachten Sie das führende Leerzeichen). An diesem Punkt sollten Sie "saubere" Pfade erhalten, viele von ihnen werden mehr als einmal vorkommen (mit unterschiedlichen Nummern vidir).

  4. Verwenden Sie sort -k 2diese Option, um nach diesen Pfaden zu sortieren. Dank -sder ersteren Analysissollte der ersteren noch vorangehen Analysis (1).

  5. Verwenden Sie uniq -f 1diese Option, um doppelte Pfade zu löschen. Jetzt sollte jeder Pfad nur einmal vorkommen.

  6. Überprüfen Sie die Vernunft der im Ergebnis verschlüsselten Verzeichnisstruktur.

  7. Fügen Sie das Ergebnis in den ursprünglichen Editor ein, speichern Sie die Datei und beenden Sie den Editor. vidirentfernt Objekte, die fehlenden Nummern zugeordnet sind, und Objekte, die verbleibenden Nummern zugeordnet sind.


Testen

Ich würde diese Lösung zuerst verwenden , um die Verzeichnisstruktur zu replizieren:

cp -a --attributes-only /mountpoint/ /guinea_pig_dir/ 

und testen Sie die Prozedur für die resultierenden leeren Dateien. Dies sollte Probleme aufdecken (falls vorhanden) und die Methode hoffentlich verbessern.


Mögliche Probleme

  1. vidir weigert sich, mit einigen nicht standardmäßigen Zeichen zu arbeiten.

  2. Im Allgemeinen ist die Reihenfolge der Objekte wichtig. Es gibt wenige Fallstricke, die Objekte erzeugen foo~oder foo~1, foo~2wenn eine Kollision mit auftritt foo. Sie werden Ihren Verzeichnisbaum so zusammenziehen, dass keine Kollisionen erzeugt werden. Ich habe jedoch noch nicht alle möglichen Szenarien untersucht. Ich denke wirklich, Sie sollten damit experimentieren /guinea_pig_dir/und sehen, was Sie bekommen. Im Fall von Problemen vielleicht einem klugen sortzwischen findund vidirhelfen.

1
cfp

Unten ist ein Bash-Skript, das diese Aufgabe ausführt. Es funktioniert zB auf MSYS2 Bash mit hinzugefügtem rsync. Es ist aus dieser verwandten Frage hier entnommen:

Skript zum Deduplizieren von Dateien und Ordnern mit einem bestimmten Suffix

#!/usr/bin/bash IFS=$'\n'; set -f #Go deepest first to deal with copies within copied folders. for copy in $(find . -regextype posix-egrep -regex "^.*\ \([0-9]+\)\s*(\.[^/.]*)?$" | awk '' | sort -rnk1 | cut -f2-); do orig=$(rev <<< "$copy" | sed -E 's/\)[0-9]+\(\ //' | rev) if [ "$orig" != "$copy" ]; then if [ -f "$orig" ]; then if [ -f "$copy" ]; then echo "File pair: $orig $copy" if diff -q "$orig" "$copy" &>/dev/null; then echo "Removing file: $copy" rm -f "$copy"; fi fi  fi if [ -d "$orig" ]; then if [ -d "$copy" ]; then echo "Folder pair: $orig $copy" if rmdir "$copy" &>/dev/null; then #If the "copy" was an empty directory then we've removed it and so we're done. echo "Removed empty folder: $copy" else #Non-destructively ensure that both folders have the same files at least.  rsync -aHAv --ignore-existing "$orig/" "$copy" &>/dev/null rsync -aHAv --ignore-existing "$copy/" "$orig" &>/dev/null if diff -qr "$orig" "$copy" &>/dev/null; then echo "Removing folder: $copy" rm -rf "$copy"; fi  fi fi fi fi done unset IFS; set +f 
Wie würde ich ein Startverzeichnis in diesem Skript festlegen? Sowohl beim Testen als auch beim endgültigen Rollout möchte ich nur, dass es mit einer bestimmten Teilmenge meiner Dateien arbeitet. Beispiel: 'G: \ My Drive \ Deduplicate_Test_Folder' PS: Vielen Dank für die unglaubliche Antwort! Josh vor 5 Jahren 0
Starten Sie einfach in diesem Ordner. (Dh `cd` dort.) cfp vor 5 Jahren 0