Parallele Dateikopie von einer Quelle zu mehreren Zielen?


15

Ich habe mehrere große Dateien auf optischen Medien, die ich auf mehrere Ziele kopieren möchte. In diesem Fall sind zwei Festplatten an denselben Computer angeschlossen. Gibt es ein Dienstprogramm, das wie folgt funktionieren kann:

copy source target1 target2 ... targetN

Antworten:


23

Für einzelne Dateien können Sie teezum Kopieren an mehrere Stellen verwenden:

cat <inputfile> | tee <outfile1> <outfile2> > <outfile3>

oder wenn Sie die demoggified Version bevorzugen:

tee <outfile1> <outfile2> > <outfile3> < <inputfile>

Beachten Sie, dass als Dennis weist darauf hin , in den Kommentaren teeAusgänge stdoutsowie die aufgelisteten Dateien, also zu Punkt Datei 3 in den obigen Beispielen mit Umleitung. Sie können dies auch /dev/nullwie folgt umleiten - dies hat den Vorteil, dass die Dateiliste in der Befehlszeile konsistenter bleibt (was das Erstellen eines Skripts für eine variable Anzahl von Dateien erleichtern kann), ist jedoch etwas weniger effizient (obwohl die Effizienzunterschied ist gering: ungefähr gleich dem Unterschied zwischen der Verwendung der catVersion oder der Version ohne cat):

cat <inputfile> | tee <outfile1> <outfile2> <outfile3> > /dev/null

Sie könnten wahrscheinlich eine der oben genannten findMöglichkeiten mit der einfachen Möglichkeit kombinieren , mehrere Dateien in einem Verzeichnis zu bearbeiten, und weniger mit Dateien, die über eine Verzeichnisstruktur verteilt sind. Andernfalls müssen Sie die mehrfachen Kopiervorgänge möglicherweise nur als separate Aufgaben parallel auslösen und hoffen, dass der Festplatten-Cache des Betriebssystems hell und / oder groß genug ist, damit jede der parallelen Aufgaben zwischengespeicherte Lesedaten vom ersten verwendet, anstatt Laufwerkskopf zu verursachen Prügel.

VERFÜGBARKEIT: teeist allgemein auf Standard-Linux-Setups und anderen Unix- oder Unix-ähnlichen Systemen verfügbar, normalerweise als Teil des GNU-Pakets "coreutils". Wenn Sie mit Windows arbeiten (Ihre Frage gibt es nicht), sollten Sie es in den verschiedenen Windows-Ports wie Cygwin finden.

PROGRESSINFORMATIONEN: Da das Kopieren einer großen Datei von optischen Medien einige Zeit dauern kann (oder über ein langsames Netzwerk oder eine noch größere Datei von sogar lokalen schnellen Medien), können Fortschrittsinformationen hilfreich sein. Auf der Kommandozeile neige ich dazu verwenden , Rohr - Viewer (in den meisten Linux - Distributionen und viele Windows - Port Sammlungen und einfach selbst zu kompilieren , wo nicht vorhanden direkt) für diese - ersetzen Sie einfach catmit in pvetwa so:

pv <inputfile> | tee <outfile1> <outfile2> > <outfile3>

Ich fand tee.exe als Teil des UnxUtils-Pakets. Danke für den tollen Tipp!
Goyuix

5
Beachten Sie, dass teedie Ausgabe auch auf stdout erfolgt, was Sie möglicherweise tun möchten, tee outputfile1 outputfile2 < inputfile > /dev/nullda die Ausgabe einer Binärdatei auf dem Terminal verrauscht sein und die Einstellungen beeinträchtigen kann.
Bis auf weiteres angehalten.

Verwenden Sie für Verzeichnisse und mehrere Dateien einfach tar anstelle von cat. Zum Beispieltar cf - file1 file2 | tee >(tar xf - -C ouput1) | tar xf - -C output2
CR.

5

Für Windows:

n2ncopy macht das:

Alt-Text

Für Linux:

Der cpBefehl allein kann von mehreren Quellen, aber leider nicht von mehreren Zielen kopiert werden. Sie müssen es mehrmals in einer Schleife ausführen. Sie können eine Schleife wie folgt verwenden und alle Verzeichnisnamen in eine Datei einfügen:

OLDIFS=$IFS
IFS=$'\n'

for line in $(cat file.txt):
do
   cp file $line
done

IFS=$OLDIFS

oder benutze xargs:

echo dir1 dir2 dir3 | xargs -n 1 cp file1

In beiden Fällen können Sie ganze Verzeichnisse / mehrere Dateien kopieren. Dies wird auch in diesem StackOverflow-Artikel erläutert .


Der N2NCopy-Link scheint unterbrochen zu sein.
Wesley


4

Basierend auf der Antwort auf eine ähnliche Frage Eine andere Möglichkeit besteht darin, mit GNU Parallel mehrere cpInstanzen gleichzeitig auszuführen :

parallel -j 0 -N 1 cp file1 ::: Destination1 Destination2 Destination3

Der obige Befehl kopiert Datei1 parallel in alle drei Zielordner


2

In Bash (Linux, Mac oder Cygwin):

cat source | tee target1 target2 >targetN

(tee kopiert seine Eingabe in STDOUT, verwenden Sie also die Umleitung für das letzte Ziel).

In Windows ist Cygwin oft zu viel des Guten. Stattdessen können Sie einfach die Exes aus dem UnxUtils- Projekt hinzufügen , darunter cat, tee und viele andere.


1

Ryan Thompsons Lösung:

for x in dest1 dest2 dest3; do cp srcfile $x &>/dev/null &; done; wait;

Sinnvoll: Wenn die Schreibgeschwindigkeit der Zielverzeichnisse ungefähr gleich ist, wird srcfile nur einmal von der Festplatte gelesen. Der Rest der Zeit wird aus dem Cache gelesen.

Ich würde es etwas allgemeiner machen, so dass Sie auch subdirs bekommen:

for x in dest1 dest2 dest3; do cp -a srcdir $x &; done; wait;

Wenn die Schreibgeschwindigkeit der Zielverzeichnisse sehr unterschiedlich ist (z. B. eines auf einer RAM-Festplatte und das andere auf NFS), können Sie feststellen, dass die Teile von srcdir, die beim Kopieren von srcdir nach dest1 gelesen wurden, sich beim Schreiben nicht mehr im Festplatten-Cache befinden dest2.


1

Nach dieser Antwort: /superuser//a/1064516/702806

Eine bessere Lösung ist die Verwendung tarund tee. Der Befehl ist komplizierter, tarscheint aber sehr leistungsfähig für die Übertragung zu sein UND muss nur einmal die Quelle lesen.

tar -c /source/dirA/ /source/file1 | tee >(cd /foo/destination3/; tar -x) >(cd /bar/destination2/; tar -x) >(cd /foobar/destination1/; tar -x) > /dev/null

Um es in einem Skript zu verwenden, müssen Sie möglicherweise Ihr Skript mit starten bash -x script.sh


Komisch. Ich dachte, "das macht Sinn, habe eine Gegenstimme". Upvoted. Dann habe ich den Link überprüft…: D
Kamil Maciorowski 10.04.17

Dies ist der (akzeptierten) Antwort von David Spillett ziemlich deutlich überlegen, wenn Sie mehrere Dateien gleichzeitig kopieren. Der einzige Vorteil, den ich beim Hinzufügen einer einzelnen Quelldatei sehen kann, tarist, dass Dateiattribute (z. B. Änderungsdatum / -zeit, (Schutz-) Modus und potenzielle ACLs, Eigentümer / Gruppe (falls privilegiert), SELinux automatisch kopiert (beibehalten) werden Kontext (falls zutreffend), erweiterte Attribute (falls zutreffend) usw.)…………… PS Warum sollte der Benutzer verwenden müssen bash -x?
Scott

Ich habe #!/bin/sham Anfang meines Skripts verwendet, aber die Syntax des Befehls wird nicht akzeptiert. Sie können bash -xoder #!/bin/basham Anfang Ihrer Datei verwenden. Ich weiß nicht , warum es einen Unterschied zwischen ist shund bashInterpretationen.
Rémi Girard

Kamil Maciorowski - Ich weiß nicht, warum Ihre Antwort nicht positiv bewertet wurde. Es ist die perfekte Lösung. Ich wollte es teilen.
Rémi Girard

0

In der Bash:

for x in dest1 dest2 dest3; do cp srcfile $x &>/dev/null &; done; wait;

2
Ich denke nicht, dass dies gut abschneiden wird. in einer idealerweise parallelen Kopie würden Sie einmal lesen und mehrmals schreiben. Ich denke, dies wird 1: 1 lesen: schreiben. Wenn die Kopien schnell genug starten und der Laufwerkscache groß genug ist, müssen Sie möglicherweise nicht nach den Leseköpfen suchen.
Quack Quijote

0

Wenn Sie dies in Windows von PowerShell aus tun möchten, ist dies standardmäßig nicht möglich, da im Gegensatz zum -PathArgument -Destinationnicht mehrere Argumente verwendet werden. Sie können -Passthroughdie Befehle jedoch verwenden und verketten. (Aber das macht keinen Spaß.)

Die beste Lösung ist Ihre eigenen zu machen, wie es dargestellt ist hier .

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.