Respuestas:
Para archivos individuales, puede usar tee
para copiar en varios lugares:
cat <inputfile> | tee <outfile1> <outfile2> > <outfile3>
o si prefiere la versión demoggified:
tee <outfile1> <outfile2> > <outfile3> < <inputfile>
Tenga en cuenta que, como señala Dennis en los tee
resultados de los comentarios stdout
, así como en los archivos enumerados, por lo tanto, utilice la redirección para señalar el archivo 3 en los ejemplos anteriores. También puede redirigir esto a /dev/null
lo siguiente: tiene la ventaja de mantener la lista de archivos más coherente en la línea de comando (lo que puede facilitar la creación de una solución para un número variable de archivos) pero es un poco menos eficiente (aunque el La diferencia de eficiencia es pequeña: aproximadamente la misma que la diferencia entre usar la cat
versión o la versión sin cat
):
cat <inputfile> | tee <outfile1> <outfile2> <outfile3> > /dev/null
Probablemente podría combinar uno de los anteriores con find
bastante facilidad para operar en múltiples archivos en un directorio y con menos facilidad para operar en archivos distribuidos en una estructura de directorio. De lo contrario, es posible que tenga que configurar las operaciones de copia múltiple en paralelo como tareas separadas y esperar que la memoria caché del disco del sistema operativo sea brillante y / o lo suficientemente grande como para que cada una de las tareas paralelas utilice datos de lectura almacenados en caché desde el primero en lugar de causar cabeza de unidad paliza.
DISPONIBILIDAD: tee
está comúnmente disponible en configuraciones estándar de Linux y otros sistemas unix o unix-like, generalmente como parte del paquete GNU "coreutils". Si está utilizando Windows (su pregunta no especifica), debería encontrarlo en los distintos puertos de Windows, como Cygwin.
INFORMACIÓN DE PROGRESO: Como copiar un archivo grande de un medio óptico puede llevar algo de tiempo (o en una red lenta, o un archivo aún más grande incluso de medios rápidos locales), la información de progreso puede ser útil. En la línea de comandos, tiendo a usar el visor de tuberías (disponible en la mayoría de las distribuciones de Linux y muchas colecciones de puertos de Windows y fácil de compilar donde no esté disponible directamente) para esto, solo reemplácelo cat
con pv
lo siguiente:
pv <inputfile> | tee <outfile1> <outfile2> > <outfile3>
tee
también se enviará a stdout, por lo que es posible que desee hacerlo, tee outputfile1 outputfile2 < inputfile > /dev/null
ya que la salida de un archivo binario al terminal puede ser ruidosa y afectar su configuración.
tar cf - file1 file2 | tee >(tar xf - -C ouput1) | tar xf - -C output2
Para ventanas:
n2ncopy hará esto:
Para Linux:
El cp
comando solo puede copiar desde múltiples fuentes pero desafortunadamente no desde múltiples destinos. Deberá ejecutarlo varias veces en un ciclo de algún tipo. Puede usar un bucle como este y colocar todos los nombres de directorio en un archivo:
OLDIFS=$IFS
IFS=$'\n'
for line in $(cat file.txt):
do
cp file $line
done
IFS=$OLDIFS
o usa xargs:
echo dir1 dir2 dir3 | xargs -n 1 cp file1
Ambos le permitirán copiar directorios completos / múltiples archivos. Esto también se discute en este artículo de StackOverflow.
Basado en la respuesta dada para una pregunta similar Otra forma es usar GNU Parallel para ejecutar múltiples cp
instancias a la vez:
parallel -j 0 -N 1 cp file1 ::: Destination1 Destination2 Destination3
El comando anterior copiará el archivo1 a las tres carpetas de destino en paralelo
En bash (Linux, Mac o Cygwin):
cat source | tee target1 target2 >targetN
(tee copia su entrada a STDOUT, así que use la redirección en el último objetivo).
En Windows, Cygwin es a menudo excesivo. En cambio, solo puede agregar los exes del proyecto UnxUtils , que incluyen cat, tee y muchos otros.
La solución de Ryan Thompson:
for x in dest1 dest2 dest3; do cp srcfile $x &>/dev/null &; done; wait;
tiene mucho sentido: si la velocidad de escritura de los directorios de destino es aproximadamente la misma, srcfile solo se leerá una vez desde el disco. El resto del tiempo se leerá desde la memoria caché.
Lo haría un poco más general, por lo que también obtienes subdirs:
for x in dest1 dest2 dest3; do cp -a srcdir $x &; done; wait;
Si la velocidad de escritura de los directorios de destino es muy diferente (por ejemplo, uno está en un disco RAM y el otro en NFS), puede ver que las partes de srcdir leen al copiar srcdir a dest1 ya no está en la memoria caché del disco al escribir dest2.
De acuerdo con esta respuesta: /superuser//a/1064516/702806
Una mejor solución es usar tar
y tee
. El comando es más complicado pero tar
parece ser muy poderoso para transferir Y necesita leer la fuente solo una vez.
tar -c /source/dirA/ /source/file1 | tee >(cd /foo/destination3/; tar -x) >(cd /bar/destination2/; tar -x) >(cd /foobar/destination1/; tar -x) > /dev/null
Para usarlo en un script, es posible que deba iniciar su script con bash -x script.sh
tar
es que copiará (preservará) automáticamente los atributos del archivo (por ejemplo, fecha / hora de modificación, modo (protección) y posiblemente ACL, propietario / grupo (si tiene privilegios), SELinux contexto (si corresponde), atributos extendidos (si corresponde), etc.) ... ... ... ... ... ... PS ¿Por qué el usuario necesitaría usar bash -x
?
#!/bin/sh
al comienzo de mi script pero no se acepta la sintaxis del comando. Puede usar bash -x
o #!/bin/bash
al principio de su archivo. No sé por qué hay una diferencia entre sh
e bash
interpretaciones.
En bash:
for x in dest1 dest2 dest3; do cp srcfile $x &>/dev/null &; done; wait;
Si desea hacer esto en Windows desde PowerShell, no es posible por defecto, porque a diferencia del -Path
argumento, el -Destination
no toma múltiples argumentos. Sin embargo, puede usar -Passthrough
y encadenar los comandos. (Pero eso no es divertido).
La mejor solución es hacer la suya, como se muestra aquí .