Ist es möglich, eine einzelne Datei mit dem Befehl cp in mehrere Verzeichnisse zu kopieren?
Ich habe folgendes ausprobiert, was nicht funktioniert hat:
cp file1 /foo/ /bar/
cp file1 {/foo/,/bar}
Ich weiß, dass es möglich ist, eine for-Schleife zu verwenden oder zu finden. Aber ist es mit dem Befehl gnu cp möglich?
Nein, cp
kann mehrere Quellen kopieren, kopiert jedoch nur an ein einziges Ziel. Sie müssen festlegen, dass cp
mehrmals aufgerufen wird - einmal pro Ziel - für das, was Sie tun möchten. Verwenden Sie, wie Sie sagen, eine Schleife oder ein anderes Werkzeug.
Sie können dies nicht nur mit cp
tun, sondern Sie können cp
mit xargs
kombinieren:
echo dir1 dir2 dir3 | xargs -n 1 cp file1
Kopiert file1
bis dir1
, dir2
, und dir3
. xargs
ruft dazu dreimal cp
auf. Weitere Informationen finden Sie auf der Manpage für xargs
.
Platzhalter funktionieren auch mit Roberts Code
echo ./fs*/* | xargs -n 1 cp test
Soweit ich es sehe, können Sie Folgendes verwenden:
ls | xargs -n 1 cp -i file.dat
Die Option -i
Des Befehls cp
bedeutet, dass Sie gefragt werden, ob Sie eine Datei im aktuellen Verzeichnis mit file.dat
Überschreiben möchten. Obwohl es keine vollautomatische Lösung ist, hat es für mich funktioniert.
Ich würde cat
und tee
basierend auf den Antworten verwenden, die ich unter https://superuser.com/questions/32630/parallel-file-copy-from-single-source) gesehen habe -zu-mehreren-Zielen anstelle von cp
.
Beispielsweise:
cat <inputfile> | tee <outfile1> <outfile2> > /dev/null
Diese Antworten scheinen alle komplizierter als das Offensichtliche:
for i in /foo /bar; do cp "$file1" "$i"; done
ls -db di*/subdir | xargs -n 1 cp File
-b
falls es ein Leerzeichen im Verzeichnisnamen gibt sonst wird es von xargs als ein anderes Element gebrochen, hatte dieses Problem mit der Echo-Version
Nicht mit CP per se, aber ...
Dies ergab sich für mich im Zusammenhang mit dem Kopieren vieler Gopro-Aufnahmen von einer (langsamen) SD-Karte auf drei (langsame) USB-Laufwerke. Ich wollte die Daten nur einmal lesen, weil es ewig gedauert hat. Und ich wollte es rekursiv.
$ tar cf - src | tee >( cd dest1 ; tar xf - ) >( cd dest2 ; tar xf - ) | ( cd dest3 ; tar xf - )
(Und Sie können weitere dieser> () - Abschnitte hinzufügen, wenn Sie mehr Ausgaben wünschen.)
Ich habe das nicht bewertet, aber es ist definitiv viel schneller als cp-in-a-loop (oder eine Reihe von parallelen cp-Aufrufen).
Um das Kopieren mit xargs
in Verzeichnisse unter Verwendung von Platzhaltern unter Mac OS zu verwenden, ist die einzige Lösung, die für mich funktioniert hat mit Leerzeichen im Verzeichnisnamen:
find ./fs*/* -type d -print0 | xargs -0 -n 1 cp test
Wobei test
die zu kopierende Datei ist
Und ./fs*/*
Die Verzeichnisse, in die kopiert werden soll
Das Problem ist, dass xargs Leerzeichen als neues Argument ansieht. Die Lösung, das Trennzeichen mit -d
Oder -E
Zu ändern, funktioniert unter Mac OS leider nicht richtig.
Wenn Sie es ohne einen Forked-Befehl tun möchten:
tee <inputfile file2 file3 file4 ... >/dev/null
Im Wesentlichen äquivalent zur Antwort von xargs, aber falls Sie eine parallele Ausführung wünschen:
parallel -q cp file1 ::: /foo/ /bar/
So kopieren Sie beispielsweise file1 in alle Unterverzeichnisse des aktuellen Ordners (einschließlich Rekursion):
parallel -q cp file1 ::: `find -mindepth 1 -type d`
NB .: Dies vermittelt wahrscheinlich nur merkliche Geschwindigkeitsgewinne für sehr spezielle Anwendungsfälle, z. wenn jedes Zielverzeichnis eine eigene Festplatte ist.
Es ähnelt auch funktional dem Argument '-P' für xargs.
Verwendung eines Bash-Skripts
DESTINATIONPATH[0]="xxx/yyy"
DESTINATIONPATH[1]="aaa/bbb"
..
DESTINATIONPATH[5]="MainLine/USER"
NumberOfDestinations=6
for (( i=0; i<NumberOfDestinations; i++))
do
cp SourcePath/fileName.ext ${DESTINATIONPATH[$i]}
done
exit
ls -d */ | xargs -iA cp file.txt A
Angenommen, Sie möchten fileName.txt
In alle Unterverzeichnisse des aktuellen Arbeitsverzeichnisses kopieren.
Holen Sie sich alle Unterverzeichnisse Namen durch ls
und speichern Sie sie in eine temporäre Datei sagen, allFolders.txt
ls > allFolders.txt
Drucken Sie die Liste aus und übergeben Sie sie an den Befehl xargs
.
cat allFolders.txt | xargs -n 1 cp fileName.txt
Nein, du kannst nicht.
Ich habe bei mehreren Gelegenheiten festgestellt, dass ich diese Funktionalität nutzen kann, also habe ich mein eigenes Tool entwickelt, um dies für mich zu tun.
http://github.com/ddavison/branch
ziemlich einfach -branch myfile dir1 dir2 dir3
Eine andere Möglichkeit besteht darin, cat und tee wie folgt zu verwenden:
cat <source file> | tee <destination file 1> | tee <destination file 2> [...] > <last destination file>
Ich denke, dies wäre jedoch ziemlich ineffizient, da der Job auf mehrere Prozesse aufgeteilt würde (einer pro Ziel) und die Festplatte mehrere Dateien gleichzeitig über verschiedene Teile des Platters schreiben würde. Wenn Sie jedoch eine Datei auf mehrere Laufwerke schreiben möchten, ist diese Methode wahrscheinlich sehr effizient (da alle Kopien gleichzeitig erstellt werden können).
Wenn alle Ihre Zielverzeichnisse mit einem Pfadausdruck übereinstimmen - als wären sie alle Unterverzeichnisse von path/to
- dann benutze einfach find
in Kombination mit cp
wie folgt:
find ./path/to/* -type d -exec cp [file name] {} \;
Das ist es.