Comment copier un fichier dans plusieurs répertoires à l'aide de la commande gnu cp

Est-il possible de copier un seul fichier dans plusieurs répertoires en utilisant la commande cp ?

J'ai essayé ce qui suit, qui n'a pas fonctionné:

cp file1 /foo/ /bar/
cp file1 {/foo/,/bar}

Je sais qu'il est possible d'utiliser une boucle for, ou find. Mais est-ce possible en utilisant la commande gnu cp?

178
demandé sur jww 2008-10-12 20:21:56

21 réponses

Non, cp peut copier plusieurs sources mais ne copiera que vers une seule destination. Vous devez vous arranger pour appeler cp plusieurs fois-une fois par destination - pour ce que vous voulez faire; en utilisant, comme vous le dites, une boucle ou un autre outil.

88
répondu moonshadow 2008-10-12 16:28:07

, Vous ne pouvez pas faire cela avec cp seul, mais vous pouvez combiner cp avec xargs:

echo dir1 dir2 dir3 | xargs -n 1 cp file1

Copie file1 pour dir1, dir2, et dir3. xargs appellera cp 3 fois pour ce faire, voir la page de man pour xargs pour plus de détails.

531
répondu Robert Gamble 2008-10-12 20:15:42

Les caractères génériques fonctionnent également avec le code Roberts

echo ./fs*/* | xargs -n 1 cp test 
70
répondu Paul 2011-01-26 10:34:51

Pour autant que je puisse le voir, vous pouvez utiliser ce qui suit:

ls | xargs -n 1 cp -i file.dat

L'option -i de la commande cp signifie qu'il vous sera demandé de remplacer un fichier dans le répertoire courant par file.dat. Bien que ce ne soit pas une solution complètement automatique, cela a fonctionné pour moi.

18
répondu Evgeny 2012-01-10 00:37:43

J'utiliserais cat et tee en fonction des réponses que j'ai vues à https://superuser.com/questions/32630/parallel-file-copy-from-single-source-to-multiple-targets au lieu de cp.

Par exemple:

cat <inputfile> | tee <outfile1> <outfile2> > /dev/null
17
répondu deterb 2017-03-20 10:18:21

ls -db di*/subdir | xargs -n 1 cp File

-b dans le cas où il y a un espace dans le nom du répertoire sinon il sera cassé comme un élément différent par xargs, a eu ce problème avec la version echo

8
répondu thAAAnos 2015-07-23 19:30:08

Ces réponses semblent toutes plus compliquées que l'évidence:

for i in /foo /bar; do cp "$file1" "$i"; done
7
répondu Waxrat 2017-01-02 20:36:29

Ne pas utiliser cp en soi, mais...

Cela m'est venu dans le contexte de la copie de beaucoup de séquences Gopro sur une carte SD (lente) sur trois lecteurs USB (lents). Je voulais lire les données une seule fois, parce que cela a pris une éternité. Et je le voulais récursif.

$ tar cf - src | tee >( cd dest1 ; tar xf - ) >( cd dest2 ; tar xf - ) | ( cd dest3 ; tar xf - )

(et vous pouvez ajouter plus de ces sections > () si vous voulez plus de sorties.)

Je n'ai pas comparé cela, mais c'est certainement beaucoup plus rapide que cp-in-a-loop (ou un tas d'invocations CP parallèles).

6
répondu oggust 2016-06-21 18:21:33

Si vous voulez le faire sans une commande fourchue:

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

3
répondu Taywee 2014-03-31 01:31:54

Pour utiliser la copie avec xargs dans les répertoires à l'aide de caractères génériques sur Mac OS, la seule solution qui a fonctionné pour moi avec Espaces Dans le nom du répertoire est:

find ./fs*/* -type d -print0 | xargs -0 -n 1 cp test 

test est le fichier à copier
Et ./fs*/* les répertoires à copier dans

Le problème est que xargs voit les espaces comme un nouvel argument, les solutions pour changer le caractère de délimiteur en utilisant -d ou -E ne fonctionnent malheureusement pas correctement sur Mac OS.

3
répondu MegaCookie 2017-08-01 17:19:32

Essentiellement équivalent à la réponse xargs, mais au cas où vous souhaiteriez une exécution parallèle:

parallel -q cp file1 ::: /foo/ /bar/

Ainsi, par exemple, pour copier file1 dans tous les sous-répertoires du dossier courant (y compris la récursivité):

parallel -q cp file1 ::: `find -mindepth 1 -type d`

N.B.: cela ne transmet probablement que des gains de vitesse notables pour des cas d'utilisation très spécifiques, par exemple si chaque répertoire cible est un disque distinct.

Il est aussi fonctionnellement similaire à l'argument'- P ' pour xargs.

2
répondu alainv 2014-06-01 22:10:13

Non - vous ne pouvez pas.

J'ai trouvé à plusieurs reprises que je pouvais utiliser cette fonctionnalité, donc j'ai fait mon propre outil pour le faire pour moi.

Http://github.com/ddavison/branch

Assez simple -
branch myfile dir1 dir2 dir3

0
répondu sircapsalot 2013-08-05 17:07:39
ls -d */ | xargs -iA cp file.txt A
0
répondu Sj Lee 2015-04-05 13:52:02

Supposons que vous vouliez copier fileName.txt dans tous les sous-répertoires du répertoire de travail actuel.

  1. Obtenez tous les noms de sous-répertoires via ls et enregistrez-les dans un fichier temporaire par exemple, allFolders.txt

    ls > allFolders.txt
    
  2. Imprimez la liste et passez-la à la commande xargs.

    cat allFolders.txt | xargs -n 1 cp fileName.txt
    
0
répondu Devendra Lattu 2016-03-21 22:38:37

Une autre façon est d'utiliser cat et tee comme suit:

cat <source file> | tee <destination file 1> | tee <destination file 2> [...] > <last destination file>

Je pense que ce serait assez inefficace, car le travail serait divisé en plusieurs processus (un par destination) et le disque dur écrirait plusieurs fichiers à la fois sur différentes parties du plateau. Cependant, si vous vouliez écrire un fichier sur plusieurs lecteurs différents, cette méthode serait probablement assez efficace (car toutes les copies pourraient se produire simultanément).

0
répondu jww 2017-01-02 20:09:12

Utilisation d'un script bash

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
0
répondu Patrick Manley 2018-08-31 21:02:41

Si vous voulez copier plusieurs dossiers sur plusieurs dossiers on peut faire quelque chose comme ceci:

Echo dir1 dir2 dir3 | xargs-n 1 cp-R /path/toyourdir/{subdir1, subdir2, subdir3}

-1
répondu Isaac 2013-10-08 23:34:57

Si vous devez être précis sur les dossiers dans lesquels copier le fichier, vous pouvez combiner find avec un ou plusieurs greps. Par exemple pour remplacer toutes les occurrences de favicon.ico dans n'importe quel sous-dossier que vous pouvez utiliser:

find . | grep favicon\.ico | xargs -n 1 cp -f /root/favicon.ico
-2
répondu Kristofer 2014-01-30 14:27:00

Cela va copier dans les sous-répertoires immédiats, si vous voulez aller plus loin, ajustez le paramètre -maxdepth.

find . -mindepth 1 -maxdepth 1 -type d| xargs -n 1 cp -i index.html

Si vous ne voulez pas copier dans tous les répertoires, espérons que vous pouvez filtrer les répertoires qui ne vous intéressent pas. Exemple de copie dans tous les dossiers commençant par a

find . -mindepth 1 -maxdepth 1 -type d| grep \/a |xargs -n 1 cp -i index.html

Si vous copiez dans un ensemble de répertoires arbitraire/disjoint, vous aurez besoin de la suggestion de Robert Gamble.

-3
répondu Hedgehog 2013-01-18 00:17:28

J'aime copier un fichier dans plusieurs répertoires en tant que tel: cp file1 /foo/; cp file1 /bar/; cp file1 /foo2/; cp file1 /bar2/ Et copier un répertoire dans d'autres répertoires: cp -r dir1/ /foo/; cp -r dir1/ /bar/; cp -r dir1/ /foo2/; cp -r dir1/ /bar2/

Je sais que c'est comme émettre plusieurs commandes, mais cela fonctionne bien pour moi quand je veux taper 1 ligne et partir pendant un moment.

-3
répondu Stace Fauske 2014-11-08 03:11:55

Par exemple, si vous êtes dans le répertoire parent de vos dossiers de destination, vous pouvez faire:

For i in $(ls); do CP sourcefile $i; done

-4
répondu Behrooz 2013-05-08 21:36:23