Comment copier un fichier dans plusieurs dossiers à l'aide de la ligne de commande?

68

J'ai essayé de copier un fichier test.txtdans plusieurs répertoires avec une seule commande:

cp ~/test.txt ~/folder1 ~/folder2

Mais je n'ai pas réussi. Existe-t-il un moyen de le faire en une seule commande pour pouvoir copier un fichier ou même un dossier dans plusieurs répertoires?

nux
la source
Pas facilement. Vous voudrez peut-être examiner «rsync» pour mettre à jour efficacement plusieurs copies d'un dossier existant
Thorbjørn Ravn Andersen
3
Essayez d'apprendre un peu de script bash. Cela peut être très utile:for dest in folder1 folder2; do cp ~/test.txt ~/"$dest"; done
Shahbaz
Pas une seule commande, mais pourrait aider certaines personnes qui tombent sur ici:cp ~/test.txt ~/folder1 && cp ~/test.txt ~/folder2
Manu Järvinen
Duplication de stackoverflow.com/a/195972/2097284 .
Camille Goudeseune

Réponses:

72

cppeut copier à partir de plusieurs sources, mais ne peut pas copier à plusieurs destinations. Voir man cppour plus d'informations.

La seule commande bash que je connaisse qui puisse copier / enregistrer vers plusieurs destinations est tee.

Vous pouvez l'utiliser dans votre cas comme suit:

tee ~/folder1/test.txt ~/folder2/test.txt < ~/test.txt

Notez que teeécrit également l'entrée sur la sortie standard (stdout). Donc, si vous ne le souhaitez pas, vous pouvez l’empêcher en redirigeant la sortie standard vers /dev/null:

tee ~/folder1/test.txt ~/folder2/test.txt < ~/test.txt >/dev/null
Radu Rădeanu
la source
10
Clever, c'est tricher! :)
terdon
5
+1, intelligent! Et si vous utilisez les >/dev/nulltravaux avec des fichiers binaires aussi, sans foirer le terminal ...
Rmano
1
+1 pour vous, votre homme toujours ma :), mais si je veux copier un répertoire?
Nux
2
@nux N'oubliez pas d'utiliser l' -roption avec cpdans le cas des répertoires
Radu Rădeanu
4
@nux: teecontrairement aux cpcopies, seul le contenu du fichier ignore son mode, sa propriété, son horodatage. Pour éviter de répéter le nom du fichier:f=text.txt; <~/$f tee ~/folder1/$f > ~/folder2/$f
jfs
61

Une autre façon de réaliser une copie vers plusieurs emplacements est la commande suivante:

find dir1 dir2 -exec cp file.txt {} \;

Si dir1 ou dir2 ont des sous-répertoires dans lesquels vous ne voulez pas copier le fichier, ajoutez l' -maxdepth 0option suivante:

find dir1 dir2 -maxdepth 0 -exec cp file.txt {} \;

Notez que cela écrasera chaque fichier contenu dans dir1et dir2avec son file.txtcontenu, en plus de le copier. Pour ne copier que file.txtsans affecter les autres fichiers de ces répertoires, dites findd'agir uniquement sur les répertoires:

find dir1 dir2 -type d -exec cp file.txt {} \;
Sylvain Pineau
la source
4
Belle solution! Cela me semble plus parfait qu'avec le tee.
Danatela
1
En effet, aucune redirection n’est impliquée et c’est toujours une commande.
Sylvain Pineau
2
@SylvainPineau En fait, il y en a 3: on est findet pour deux fois (dans ce cas) cp. Pour ne pas dire que findbesoin de beaucoup de temps.
Radu Rădeanu
3
Si la définition d'une "commande" est un appel "exec", peut-être, mais c'est "une commande" dans mon livre.
Kojiro
2
Je reviens toujours sur celui-ci, alors j'ai pensé que je devrais donner un vote positif: D
Jonathan
31

La commande

cp ~/test.txt ~/folder1 ~/folder2

essaie de copier deux fichiers ( ~/test.txtet ~/folder1) vers la destination folder2. (Et si ~/folder2existe et est un répertoire, vous aurez un avertissement "omitting directory").

Si vous voulez faire plusieurs copies du fichier test.txt, vous devez utiliser une boucle ou plusieurs commandes ...

for i in ~/folder1 ~/folder2; do cp  ~/test.txt $i; done 

(... et faites attention si vous avez des espaces incorporés dans les noms de fichiers, vous aurez besoin de guillemets).

Pour copier des répertoires entiers, vous devez utiliser l' -roption:

for i in ~/folder1 ~/folder2; do cp -r ~/folder3 $i; done

cela créera ~/folder1/folder3et ~/folder2/folder3avec tous les fichiers inclus.

Rmano
la source
1
Pour le lecteur qui passe: Selon la spécification , une boucle for est une commande composée. Par conséquent, il s'agit toujours d' une commande et répond à toutes les exigences de la question.
kojiro
@nux, je ne suis pas d'accord sur les corrections. 1) les deux majuscules sont fausses, mon intention était d'entrelacer les commandes dans la phrase. 2) les points de suspension sont une question de style; s'il vous plaît laissez mon style
po
1
ok, je suis désolé mec, je pensais que ça irait mieux.
Nux
sur mon système, il ne sauvegarde pas le dossier 3 sous le nom ~ / folder1 / folder3, mais copie plutôt tout le contenu du dossier 3 dans le dossier1
alpha_989
23

Vous pouvez créer un script d’aide ou le faire avec xargsune fonction d’impression (dans ce cas, echo):

echo firstDir secondDir | xargs -n 1 cp test

Cela fera de chaque répertoire un argument de la cpfonction, en utilisant le fichier test comme paramètre.

Evandro Silva
la source
C'est probablement la meilleure / la plus directe réponse à la question
Bryson S.
7

Après une longue recherche ce travail aussi comme un charme!

for dir in *; do [ -d "$dir" ] && cp /path/file.txt "$dir" ; done

Ceci copiera le fichier file.txt dans tous les répertoires de votre emplacement actuel dans le terminal.

for dir in *; do [ -d "$dir" ] && cp -rf /path/folder "$dir" ; done

Cela copiera un dossier dans chaque sous-répertoire de votre emplacement actuel dans le terminal.

Je le partage j'espère que cela aidera les autres aussi.

nux
la source
Dans zsh, vous pouvez utiliser for i in *(/); ...pour parcourir tous les sous-répertoires afin d'éviter le [ -d ...test. Extended Globbing est l'une des raisons pour lesquelles je l'aime plus bash.
Rmano
pouvez-vous redresser le code dans une commande
nux
1
Dans zsh, la première commande de cette réponse peut être simplifiée comme for dir in *(/); do cp /path/file.txt "$dir"; done. Voir zsh.sourceforge.net/Intro/intro_2.html
Rmano
5
Vous pouvez éliminer le test dans n’importe quel shell dérivé de Bourne avecfor dir in */;
Henk Langeveld
@nux Cela fonctionne vraiment bien et la commande est très facile à suivre. Il devrait être voté beaucoup plus haut!
nukeguy
1

Si vous souhaitez copier le fichier test.txt dans chaque répertoire de / tmp / target / ...

créer un environnement de test:

mkdir /tmp/target
cd /tmp/target
mkdir -v {folder1,folder2,folder3}
touch test.txt

copier le:

find * -maxdepth 0 -type d -exec cp -vi test.txt {} \;
mat
la source
0

Je viens de penser à donner une variation à la réponse de Sylvain Pineau

dir1et dir2ne sont pas dans votre répertoire actuel.

find ./ -maxdepth 2 -type d -name dir1 -exec cp file.txt {} \;

ici find cherchera dir1deux niveaux de profondeur ou vous pouvez laisser de -maxdepthparamètre à trouver dir1dans tous les dossiers du répertoire courant et en dessous.

Joshi
la source