Wie kopiere ich zwei Verzeichnisse zusammen?


112

Ich habe zwei Verzeichnisse images und images2 mit dieser Struktur in Linux:

/images/ad  
/images/fe  
/images/foo  

... und weitere 4000 Ordner

und der andere ist wie:

/images2/ad  
/images2/fe  
/images2/foo

... und weitere 4000 Ordner

Jeder dieser Ordner enthält Bilder, und die Namen der Verzeichnisse unter Bildern und Bildern2 sind identisch, unterscheiden sich jedoch in ihrem Inhalt. Dann möchte ich wissen, wie ich die Bilder von / images2 / ad in images / ad, die Bilder von / images2 / foo in images / foo usw. mit allen 4000 Ordnern kopieren und zusammenführen kann.


1
Sind die Enddateien in beiden Verzeichnissen gleich benannt?
Simply_Me

Nein ... zum Beispiel in Bildern / Anzeigen sind 1.jpg, 2.jpg und 3.jpg. Aber in images2 / ad sind 4.jpg und 5.jpg
ssierral

4
@AmirAliAkbari, ich glaube nicht, dass es sich um ein Duplikat handelt. (Antwort: nein). In dieser Frage geht es darum, wie zwei Verzeichnishierarchien zusammengeführt werden.
Maxschlepzig

Antworten:


173

Dies ist ein Job für Rsync . Es hat keinen Vorteil, dies manuell mit einer Shell-Schleife zu tun, es sei denn, Sie möchten die Datei verschieben, anstatt sie zu kopieren.

rsync -a /path/to/source/ /path/to/destination

In deinem Fall:

rsync -a /images2/ /images/

(Beachten Sie den abschließenden Schrägstrich images2, ansonsten würde er nach kopiert /images/images2.)

Wenn Bilder mit dem gleichen Namen in beiden Verzeichnissen vorhanden ist , wird der Befehl über überschrieben /images/SOMEPATH/SOMEFILEmit /images2/SOMEPATH/SOMEFILE. Wenn Sie nur ältere Dateien ersetzen möchten, fügen Sie die Option hinzu -u. Wenn Sie die Version immer beibehalten möchten /images, fügen Sie die Option hinzu --ignore-existing.

Wenn Sie die Dateien /images2mit rsync verschieben möchten , können Sie die Option übergeben --remove-source-files. Dann kopiert rsync der Reihe nach alle Dateien und entfernt jede Datei, wenn sie fertig ist. Dies ist viel langsamer als das Verschieben, wenn sich das Quell- und das Zielverzeichnis auf demselben Dateisystem befinden.


14
..add -P wenn Sie Fortschritte sehen
möchten

1
Ich möchte hinzufügen , dass es keinen Vorteil eine knifflige Schale Schleife hier auch zu verwenden , wenn Sie tun , sie wollen sich zu bewegen , anstatt zu kopieren in diesem Fall nur verwenden rsync, dann rm -r /images.
Wildcard

1
Ich möchte auch darauf hinweisen, dass es wichtig ist, die abschließenden Schrägstriche für jedes Verzeichnis einzuschließen . Wenn Sie zum Beispiel einfach ausgeführt haben rsync -a images images2, werden nur die Bilder2 in die Bilder kopiert, anstatt sie zusammenzuführen.
Kyle Challis

1
@ s3cur3 Oh. Von 2 bis (implizit) 1. Das ist nicht intuitiv. Danke, ich habe meine Antwort korrigiert.
Gilles

1
@MaxCoplan Nein. Rsync ist kein interaktives Tool.
Gilles,

43

Die beste Wahl ist natürlich rsync. Trotzdem wäre auch unisono ein tolles Stück Software, um diesen Job zu erledigen. Beide können in mehreren Betriebssystemen verwendet werden.

Rsync

rsync synchronisiert in eine Richtung von der Quelle zum Ziel. Daher die folgende Aussage

rsync -avh --progress Source Destination

Synchronisiert alles von der Quelle zum Ziel . Der zusammengeführte Ordner befindet sich in Ziel .

-a bedeutet "Archiv" und kopiert alles rekursiv von der Quelle zum Ziel, wobei fast alles erhalten bleibt.

-v gibt mehr aus ("ausführlich").

-h Für Menschen lesbar.

- Fortschritt, um zu zeigen, wie viel Arbeit geleistet wird.

Wenn Sie nur aktualisieren die Zielordner mit neueren aus Quellordnern Dateien:

rsync -avhu --progress source destination

Einklang

unisono synchronisiert in beide Richtungen. Daher die folgende Aussage

unison Source Destination

Synchronisiert beide Verzeichnisse in beide Richtungen und schließlich ist Quelle gleich Ziel. Es ist, als würde man zweimal von der Quelle zum Ziel und umgekehrt rsync ausführen.

Weitere Informationen finden Sie auf den Manpages oder auf den folgenden Websites:

  1. https://www.cis.upenn.edu/~bcpierce/unison/
  2. https://rsync.samba.org/

2
Ich möchte erwähnen, dass der korrekte Pfad zum Ordner mit dem abschließenden Schrägstrich am Ende versehen sein sollte rsync -avh --progress source/ destination/, da sonst der Quellordner im Zielordner erstellt wird, zumindest in meinem Fall, in dem dies der Fall war.
Electroid

Dies funktioniert hervorragend für mich (mit dem abschließenden Schrägstrich in Ordnern). Danke!
Leopoldo Sanczyk

5
for dir in images2/*; do mv "$dir"/* "images/$(basename "$dir")"; done

Durchlaufen Sie den gesamten Inhalt der images2Verwendung eines erweiterten Glob (um Probleme beim Parsen zu vermeiden ls) und dann mvden Inhalt dieser Elemente mit dem entsprechenden Eintrag in images. Wird verwendet basename, um die Führungslinie images2vom globbed-Pfad zu entfernen.


Bitte fügen Sie weitere Details zu den Funktionen Ihres Befehls hinzu, damit diese auch für zukünftige Leser nützlich sind :)
Ramesh

1

@ inulinux12, Sie können die folgende einzeilige forSchleife von der Befehlszeile aus verwenden:

$ for dir in images2/*; do mv "$dir"/* "${dir/2/}"; done

Dadurch werden alle Dateien aus bewegen images2zu imagesin ihren jeweiligen Verzeichnissen. Hinweis: Dies setzt voraus, dass keine Dateien den gleichen Namen haben.

Zum Beispiel:

Vor der Ausführung:

$ ls -R images*
images:
ad  adfoo  fe
images/ad:
jpg.1  jpg.2
images/adfoo:
jpg.7
images/fe:
jpg.5
images2:
ad  adfoo  fe
images2/ad:
jpg.3
images2/adfoo:
jpg.6
images2/fe:
jpg.4

Nach der Ausführung:

$ ls -R images*
images:
ad  adfoo  fe
images/ad:
jpg.1  jpg.2  jpg.3
images/adfoo:
jpg.6  jpg.7
images/fe:
jpg.4  jpg.5

3
Analysieren Sie nicht die Ausgabe von ls. mywiki.wooledge.org/ParsingLs
Etan Reisner

@EtanReisner Danke für den Vorschlag; scheint ziemlich enge Szenarien, obwohl die Informationen in der Frage gegeben.
Simply_Me

2
@Simply_Me Es stimmt zwar, dass es normalerweise in Ordnung ist, aber Sie möchten wirklich nicht, dass es explodiert, wenn Sie einen Fall treffen, auf den Sie nicht zählen. Es kann wirklich schlimme Probleme verursachen. Ganz zu schweigen davon, dass es ziemlich oft (wie in diesem Fall) fast trivial durch einen einfachen Globus ersetzt werden kann. Siehe meine Antwort als Beispiel dafür.
Etan Reisner

@Simply_Me Die Szenarien enthalten Dateinamen mit Leerzeichen, was für Bilder recht häufig ist.
Gilles

@Gilles und @Etan Reisner, danke für die Eingabe, ich weiß es zu schätzen! Meine Antwort wurde aktualisiert und getestet, um die Zeichenfolgensubstitution zu verwenden, und sie wurde schneller als basenamein dieser bestimmten Situation (es ist nicht erforderlich, dies aufzurufen basename). Nochmals vielen Dank für konstruktive Kommentare.
Simply_Me
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.