it-swarm.com.de

So kopieren Sie eine Datei mit dem Befehl gnu cp in mehrere Verzeichnisse

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?

199
Tom Feiner

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.

103
moonshadow

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.

568
Robert Gamble

Platzhalter funktionieren auch mit Roberts Code

echo ./fs*/* | xargs -n 1 cp test 
76
Paul

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.

19
Evgeny

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
17
deterb

Diese Antworten scheinen alle komplizierter als das Offensichtliche:

for i in /foo /bar; do cp "$file1" "$i"; done
9
Waxrat

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

9
thAAAnos

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).

6
oggust

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.

4
MegaCookie

Wenn Sie es ohne einen Forked-Befehl tun möchten:

tee <inputfile file2 file3 file4 ... >/dev/null

3
Taywee

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.

2
alainv

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
1
Patrick Manley
ls -d */ | xargs -iA cp file.txt A
0
Sj Lee

Angenommen, Sie möchten fileName.txt In alle Unterverzeichnisse des aktuellen Arbeitsverzeichnisses kopieren.

  1. Holen Sie sich alle Unterverzeichnisse Namen durch ls und speichern Sie sie in eine temporäre Datei sagen, allFolders.txt

    ls > allFolders.txt
    
  2. Drucken Sie die Liste aus und übergeben Sie sie an den Befehl xargs.

    cat allFolders.txt | xargs -n 1 cp fileName.txt
    
0
Devendra Lattu

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

0
ddavison

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).

0
user168046

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.

0
Mig82