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

1

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 mit der Ordnerstruktur "Name (1)" umgehen (die ich bisher feststellen kann), und alle kopieren Dateien, anstatt sie zu verschieben:

  • WinMerge für Windows 10 & lt; - Drosseln beim Kopieren von Google-Laufwerksdateien (gibt etwas "DOS-Befehl nicht unterstützt" für sie zurück)
  • Meld für MacOS. & lt; - langsam.
  • Terminal mit "ditto" -Befehl in OS X & lt;

Danke für Ihre Hilfe!

Josh
quelle
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 beispielsweise mit bewegten Dateien innerhalb eine HD-Partition, das geht schnell. Das Verschieben zwischen Partitionen, zwischen HDs, zwischen PCs usw. dauert in der Regel erheblich länger (bei bestimmten Konfigurationen keine Ausnahme).
Albin
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, verschieben Sie Dateien beim Verschieben von Dateien wie innerhalb einer HD-Partition: 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
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

Antworten:

1

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 die Freigabe also in Ihre Verzeichnisstruktur einbinden mv. cp und andere vernünftige Werkzeuge können mit Verzeichnissen so arbeiten, als wären sie lokal;
  • Dateien (oder Verzeichnisse) mit Pfaden, die identisch werden, nachdem Sie alle entfernt haben (N) Zeichenfolgen sind tatsächlich 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, einige Schritte könnten als Skript geschrieben werden, aber da ist die Lösung sehr experimentell , es ist besser, es von Hand Schritt für Schritt zu machen und darauf zu achten, was passiert.

  1. In einer Schale cd zum Mountpoint und rufen Sie auf find . | vidir -; Verwenden Sie einen Texteditor Ihrer Wahl, z. kate, so was:

    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 nach Ein weiterer 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. Benutzen sed oder jedes andere Werkzeug, um alle loszuwerden (N) Zeichenketten (beachten Sie das führende Leerzeichen). An diesem Punkt sollten Sie "saubere" Pfade erhalten, viele davon werden mehrmals vorkommen (mit unterschiedlichen Nummern, die durch angegeben werden vidir ).

  4. Benutzen sort -k 2 nach diesen Wegen sortieren. Dank an -s das Vorherige Analysis sollte dem ersteren noch vorangehen Analysis (1).

  5. Benutzen uniq -f 1 doppelte Pfade 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. vidir entfernt Objekte, die fehlenden Nummern zugeordnet sind, und Objekte, die verbleibenden Nummern zugeordnet sind.


Testen

Ich würde zuerst verwenden diese Lösung replizieren Sie die Verzeichnisstruktur:

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~2 wenn es eine Kollision mit gibt foo. Sie "verkleinern" Ihren Verzeichnisbaum auf eine Weise, die keine Kollisionen erzeugen sollte, dennoch habe ich nicht alle möglichen Szenarien untersucht. Ich denke wirklich, du solltest damit experimentieren /guinea_pig_dir/ und sehen, was Sie bekommen. Bei Problemen könnte sein ein kluger sort zwischen find und vidir wird helfen

Kamil Maciorowski
quelle
1

Unten ist ein Bash-Skript, das diese Aufgabe ausführt. Es funktioniert z. 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 '{print length($0)"\t"$0}' | 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
cfp
quelle
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
Starten Sie einfach in diesem Ordner. (D.h. cd Dort.)
cfp