Antworten:
Für einzelne Dateien können Sie tee
zum 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 tee
Ausgänge stdout
sowie die aufgelisteten Dateien, also zu Punkt Datei 3 in den obigen Beispielen mit Umleitung. Sie können dies auch /dev/null
wie 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 cat
Version oder der Version ohne cat
):
cat <inputfile> | tee <outfile1> <outfile2> <outfile3> > /dev/null
Sie könnten wahrscheinlich eine der oben genannten find
Mö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: tee
ist 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 cat
mit in pv
etwa so:
pv <inputfile> | tee <outfile1> <outfile2> > <outfile3>
tee
die Ausgabe auch auf stdout erfolgt, was Sie möglicherweise tun möchten, tee outputfile1 outputfile2 < inputfile > /dev/null
da die Ausgabe einer Binärdatei auf dem Terminal verrauscht sein und die Einstellungen beeinträchtigen kann.
tar cf - file1 file2 | tee >(tar xf - -C ouput1) | tar xf - -C output2
Für Windows:
n2ncopy macht das:
Für Linux:
Der cp
Befehl 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 .
Basierend auf der Antwort auf eine ähnliche Frage Eine andere Möglichkeit besteht darin, mit GNU Parallel mehrere cp
Instanzen gleichzeitig auszuführen :
parallel -j 0 -N 1 cp file1 ::: Destination1 Destination2 Destination3
Der obige Befehl kopiert Datei1 parallel in alle drei Zielordner
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.
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.
Nach dieser Antwort: /superuser//a/1064516/702806
Eine bessere Lösung ist die Verwendung tar
und tee
. Der Befehl ist komplizierter, tar
scheint 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
tar
ist, 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
?
#!/bin/sh
am Anfang meines Skripts verwendet, aber die Syntax des Befehls wird nicht akzeptiert. Sie können bash -x
oder #!/bin/bash
am Anfang Ihrer Datei verwenden. Ich weiß nicht , warum es einen Unterschied zwischen ist sh
und bash
Interpretationen.
In der Bash:
for x in dest1 dest2 dest3; do cp srcfile $x &>/dev/null &; done; wait;
Wenn Sie dies in Windows von PowerShell aus tun möchten, ist dies standardmäßig nicht möglich, da im Gegensatz zum -Path
Argument -Destination
nicht mehrere Argumente verwendet werden. Sie können -Passthrough
die Befehle jedoch verwenden und verketten. (Aber das macht keinen Spaß.)
Die beste Lösung ist Ihre eigenen zu machen, wie es dargestellt ist hier .