GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Gibt es eine Möglichkeit, die Verzeichnisstruktur zu synchronisieren, wenn sich die Dateien bereits auf beiden Seiten befinden?

Ich habe zwei Laufwerke mit denselben Dateien, aber die Verzeichnisstruktur ist völlig unterschiedlich.

Gibt es eine Möglichkeit, alle Dateien auf der Zielseite so zu „verschieben“, dass sie der Struktur der Quellseite entsprechen? Vielleicht mit einem Skript?

Zum Beispiel hat Laufwerk A:

/foo/bar/123.txt
/foo/bar/234.txt
/foo/bar/dir/567.txt

Wohingegen Laufwerk B hat:

/some/other/path/123.txt
/bar/doo2/wow/234.txt
/bar/doo/567.txt

Die fraglichen Dateien sind riesig (800 GB), daher möchte ich sie nicht erneut kopieren. Ich möchte nur die Struktur synchronisieren, indem ich die erforderlichen Verzeichnisse erstelle und die Dateien verschiebe.

Ich dachte an ein rekursives Skript, das jede Quelldatei auf dem Ziel findet, sie dann in ein passendes Verzeichnis verschiebt und sie bei Bedarf erstellt. Aber – das übersteigt meine Fähigkeiten!

Eine weitere elegante Lösung wurde hier gegeben:
https://superuser.com/questions/237387/any-way-to-sync-directory-structure-when-the-files-are-already-on-both-sides /238086

Akzeptierte Antwort:

Ich werde mit Gilles gehen und Sie auf Unison verweisen, wie von hasen j vorgeschlagen. Unison war DropBox 20 Jahre vor DropBox. Grundsolider Code, den viele Leute (mich eingeschlossen) jeden Tag verwenden – es lohnt sich sehr, ihn zu lernen. Trotzdem join braucht alle Publicity, die es bekommen kann 🙂

Das ist nur eine halbe Antwort, aber ich muss mich wieder an die Arbeit machen 🙂

Im Grunde wollte ich den wenig bekannten join demonstrieren Dienstprogramm, das genau das tut:Verbindet zwei Tabellen in einem Feld.

Erstellen Sie zunächst einen Testfall mit Dateinamen mit Leerzeichen:

for d in a b 'c c'; do mkdir -p "old/$d"; echo $RANDOM > "old/${d}/${d}.txt"; done
cp -r old new

(Bearbeiten Sie einige Verzeichnis- und/oder Dateinamen in new ).

Jetzt wollen wir eine Karte erstellen:Hash -> Dateiname für jedes Verzeichnis und dann join verwenden um Dateien mit demselben Hash abzugleichen. Um die Karte zu generieren, fügen Sie Folgendes in makemap.sh ein :

find "$1" -type f -exec md5 -r "{}" ; 
  | sed "s/([a-z0-9]*) ${1}/(.*)/1 "2"/" 

makemap.sh spuckt eine Datei mit Zeilen der Form „Hash „Dateiname““ aus, also verbinden wir uns einfach mit der ersten Spalte:

join <(./makemap.sh 'old') <(./makemap.sh 'new') >moves.txt

Dies erzeugt moves.txt das sieht so aus:

49787681dd7fcc685372784915855431 "a/a.txt" "bar/a.txt"
bfdaa3e91029d31610739d552ede0c26 "c c/c c.txt" "c c/c c.txt"

Der nächste Schritt wäre, die Züge tatsächlich auszuführen, aber meine Versuche blieben beim Zitieren hängen … mv -i und mkdir -p sollte praktisch sein.

Verwandte:Wie kann man jede versteckte Datei mit Ausnahme des aktuellen und übergeordneten Verzeichnisses globen?
Linux
  1. Was ist der beste Weg, um die Anzahl der Dateien in einem Verzeichnis zu zählen?

  2. Schnelle Möglichkeit, einen Verzeichnispfad beim Aufrufen von Mv einzuschließen?

  3. Wohin gehen Dateien, wenn der Rm-Befehl ausgegeben wird?

  4. Gibt es eine Möglichkeit, mv dazu zu bringen, das Verzeichnis zu erstellen, in das verschoben werden soll, wenn es nicht existiert?

  5. Wie tariere ich ein Verzeichnis, ohne die Verzeichnisstruktur beizubehalten?

Möglichkeit, Logrotate anzuweisen, geöffnete Dateien zu ignorieren?

Zählen der Anzahl der Dateien in einem Verzeichnis mit C

Was sind die Unterschiede zwischen Linux- und Windows-.txt-Dateien (Unicode-Codierung)

Wenn Sie apt-get install ausführen, wo werden die .deb-Dateien gespeichert?

Wie erhalte ich die tatsächliche Verzeichnisgröße (aus du)?

Was ist der schnellste Weg, um alle Dateien und Unterordner in einem Verzeichnis zu entfernen?