¿Cómo copiar un archivo a múltiples carpetas usando la línea de comando?

68

He intentado copiar un archivo test.txten varios directorios con un comando:

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

Pero no tuve éxito. ¿Hay alguna manera de hacerlo en un comando para poder copiar un archivo o incluso una carpeta en varios directorios?

nux
fuente
No es fácil. Es posible que desee buscar en "rsync" para actualizar de manera eficiente múltiples copias existentes de una carpeta
Thorbjørn Ravn Andersen
3
Intenta aprender un poco de bash-script. Puede ser muy útil:for dest in folder1 folder2; do cp ~/test.txt ~/"$dest"; done
Shahbaz
No es un solo comando, pero podría ayudar a algunas personas que tropiezan aquí:cp ~/test.txt ~/folder1 && cp ~/test.txt ~/folder2
Manu Järvinen
Duplicado de stackoverflow.com/a/195972/2097284 .
Camille Goudeseune

Respuestas:

72

cppuede copiar desde múltiples fuentes, pero no puede copiar a múltiples destinos. Ver man cppara más información.

El único comando bash que sé que puede copiar / guardar en múltiples destinos es tee.

Puede usarlo en su caso de la siguiente manera:

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

Tenga en cuenta que teetambién escribe la entrada en la salida estándar (stdout). Entonces, si no desea esto, puede evitarlo redirigiendo la salida estándar de la /dev/nullsiguiente manera:

tee ~/folder1/test.txt ~/folder2/test.txt < ~/test.txt >/dev/null
Radu Rădeanu
fuente
10
¡Listo, eso es trampa! :)
terdon
55
+1, inteligente! Y si usa las >/dev/nullobras también con archivos binarios, sin estropear el terminal ...
Rmano
1
+1 para ti, siempre eres un hombre :), pero ¿y si quiero copiar un directorio?
nux
2
@nux No olvides usar la -ropción con cpen caso de directorios
Radu Rădeanu
44
@nux: a teediferencia de las cpcopias, solo el contenido del archivo ignora su modo, propiedad y marcas de tiempo. Para evitar repetir el nombre del archivo:f=text.txt; <~/$f tee ~/folder1/$f > ~/folder2/$f
jfs
61

Otra forma de lograr una copia en varias ubicaciones es el siguiente comando:

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

Si dir1 o dir2 tienen subdirectorios en los que no desea copiar el archivo, agregue la -maxdepth 0opción:

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

Tenga en cuenta que esto sobrescribirá todos los archivos en dir1y dir2con file.txtel contenido, además de copiarlo. Para copiar solo file.txtsin afectar otros archivos en estos directorios, diga findque solo actúe en los directorios:

find dir1 dir2 -type d -exec cp file.txt {} \;
Sylvain Pineau
fuente
44
Buena solución! Me parece más perfecto que con tee.
Danatela
1
De hecho, no hay redirección involucrada y todavía es un comando.
Sylvain Pineau
2
@SylvainPineau De hecho, hay 3: uno es findy dos veces (en este caso) cp. No quiere decir que findnecesite mucho tiempo.
Radu Rădeanu
3
Si la definición de un "comando" es una llamada "ejecutiva", tal vez, pero este es "un comando" en mi libro.
kojiro
2
Sigo volviendo a este, así que pensé que debería dar un voto positivo: D
Jonathan
31

El comando

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

intenta copiar dos archivos ( ~/test.txty ~/folder1) al destino folder2. (Y si ~/folder2existe y es un directorio, tendrá una advertencia de "omisión de directorio").

Si desea hacer múltiples copias del archivo test.txt, debe usar un bucle o múltiples comandos ...

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

(... y tenga cuidado si tiene espacios incrustados en los nombres de archivo, necesitará comillas).

Para copiar directorios completos, debe usar la -ropción:

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

esto creará ~/folder1/folder3y ~/folder2/folder3con todos los archivos incluidos.

Rmano
fuente
1
Para el lector que pasa: Según la especificación , un bucle for es un comando compuesto. Por lo tanto, este sigue siendo un comando y cumple con todos los requisitos para la pregunta.
kojiro
@nux, no estoy de acuerdo con las correcciones. 1) las dos mayúsculas están mal, mi intención era intercalar los comandos en la frase. 2) la elipsis es una cuestión de estilo; por favor deja entrar mi estilo.
Rmano
1
ok, lo siento hombre, pensé que se vería mejor.
nux
en mi sistema, no guarda la carpeta3 como ~ / carpeta1 / carpeta3, sino que copia todo en la carpeta3 en la carpeta1
alpha_989
23

Puede crear un script de ayuda, o puede hacerlo con xargsuna función de impresión (en este caso echo):

echo firstDir secondDir | xargs -n 1 cp test

Esto hará que cada directorio sea un argumento para la cpfunción, utilizando el archivo de prueba como parámetro.

Evandro Silva
fuente
Esta es probablemente la mejor / más directa respuesta a la pregunta
Bryson S.
7

¡Después de una larga búsqueda, esto también funciona como un encanto!

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

Esto copiará file.txt a cada directorio en su ubicación actual en la terminal.

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

Esto copiará una carpeta a cada subdirectorio en su ubicación actual en la terminal.

Lo comparto, espero que ayude a otros también.

nux
fuente
En zsh, puede usar for i in *(/); ...para recorrer todos los subdirectorios, para evitar la [ -d ...prueba. El globbing extendido es una de las razones por las que me gusta bash.
Rmano
puede su derecha el código de nuevo en un comando
Nux
1
En zsh, el primer comando de esta respuesta se puede simplificar como for dir in *(/); do cp /path/file.txt "$dir"; done. Ver zsh.sourceforge.net/Intro/intro_2.html
Rmano
55
Puede eliminar la prueba en cualquier shell derivado de Bourne confor dir in */;
Henk Langeveld
@nux Esto funciona muy bien y el comando es muy fácil de seguir. ¡Debería ser votado mucho más alto!
nukeguy
1

Si desea copiar el archivo test.txt en cada directorio en / tmp / target / ...

crear un entorno de prueba:

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

cópialo:

find * -maxdepth 0 -type d -exec cp -vi test.txt {} \;
mate
fuente
0

Solo pensé en dar una variación a la respuesta de Sylvain Pineau

donde dir1y dir2no están en su directorio actual.

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

aquí find buscará dir1dos niveles de profundidad o puede omitir el -maxdepthparámetro para buscar dir1en todas las carpetas en el directorio actual y debajo de él.

Joshi
fuente