Copia di file paralleli da una singola fonte a più destinazioni?


15

Ho diversi file di grandi dimensioni su supporti ottici che vorrei copiare su più destinazioni - in questo caso ho due dischi rigidi collegati allo stesso computer. Esiste un'utilità che può funzionare come:

copy source target1 target2 ... targetN

Risposte:


23

Per i singoli file è possibile utilizzare teeper copiare in più posizioni:

cat <inputfile> | tee <outfile1> <outfile2> > <outfile3>

o se preferisci la versione ridotta:

tee <outfile1> <outfile2> > <outfile3> < <inputfile>

Si noti che, come sottolinea Dennis nei commenti, vengono teeemessi stdoutanche i file elencati, quindi utilizzando il reindirizzamento per puntare al file 3 negli esempi precedenti. Potresti anche reindirizzare questo /dev/nullcome di seguito: questo ha il vantaggio di mantenere l'elenco dei file più coerente sulla riga di comando (che potrebbe rendere più semplice lo scripting di una soluzione per un numero variabile di file) ma è un po 'meno efficiente (sebbene il la differenza di efficienza è piccola: quasi uguale alla differenza tra l'utilizzo della catversione o della versione senza cat):

cat <inputfile> | tee <outfile1> <outfile2> <outfile3> > /dev/null

Probabilmente potresti combinare uno dei precedenti con findabbastanza facilmente operare su più file in una directory e meno facilmente operare su file distribuiti su una struttura di directory. Altrimenti potresti dover semplicemente impostare le operazioni multiple di copia in parallelo come attività separate e sperare che la cache del disco del sistema operativo sia luminosa e / o abbastanza grande da far sì che ciascuna delle attività parallele utilizzi i dati di lettura memorizzati nella cache dal primo invece di causare testata botte.

DISPONIBILITÀ: teeè comunemente disponibile su configurazioni Linux standard e altri sistemi unix o unix-like, di solito come parte del pacchetto "coreutils" GNU. Se stai usando Windows (la tua domanda non specifica), dovresti trovarlo nelle varie porte di Windows come Cygwin.

INFORMAZIONI SUL PROGRESSO: Dal momento che la copia di un file di grandi dimensioni da supporti ottici può richiedere del tempo (o su una rete lenta o un file ancora più grande anche da un supporto veloce locale), le informazioni sullo stato di avanzamento possono essere utili. Sulla riga di comando tendo a usare il visualizzatore di pipe (disponibile nella maggior parte delle distribuzioni Linux e in molte raccolte di porte Windows e facile da compilare laddove non disponibile direttamente) per questo - basta sostituirlo catcon pvcosì:

pv <inputfile> | tee <outfile1> <outfile2> > <outfile3>

Ho trovato tee.exe come parte del pacchetto UnxUtils. Grazie per l'ottimo consiglio!
Goyuix,

5
Notare che teeverrà anche emesso su stdout, quindi potresti voler fare tee outputfile1 outputfile2 < inputfile > /dev/nullpoiché l'output di un file binario sul terminale potrebbe essere rumoroso e incasinato con le sue impostazioni.
In pausa fino a ulteriore avviso.

Per directory e file multipli basta usare tar invece di cat. Ad esempiotar cf - file1 file2 | tee >(tar xf - -C ouput1) | tar xf - -C output2
CR.

5

Per Windows:

n2ncopy farà questo:

testo alternativo

Per Linux:

Il cpcomando da solo può copiare da più origini ma sfortunatamente non più destinazioni. Dovrai eseguirlo più volte in un ciclo di qualche tipo. È possibile utilizzare un ciclo in questo modo e posizionare tutti i nomi di directory in un file:

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

Entrambi permetteranno di copiare intere directory / file multipli. Questo è anche discusso in questo articolo StackOverflow.


Il collegamento N2NCopy sembra essere rotto.
Wesley,


4

Basato sulla risposta fornita per una domanda simile Un altro modo è usare GNU Parallel per eseguire più cpistanze contemporaneamente:

parallel -j 0 -N 1 cp file1 ::: Destination1 Destination2 Destination3

Il comando sopra copierà file1 in tutte e tre le cartelle di destinazione in parallelo


2

In bash (Linux, Mac o Cygwin):

cat source | tee target1 target2 >targetN

(Tee copia il suo input su STDOUT, quindi usa il reindirizzamento sull'ultimo target).

In Windows, Cygwin è spesso eccessivo. Invece, puoi semplicemente aggiungere gli ex dal progetto UnxUtils , che includono cat, tee e molti altri.


1

La soluzione di Ryan Thompson:

for x in dest1 dest2 dest3; do cp srcfile $x &>/dev/null &; done; wait;

ha molto senso: se la velocità di scrittura delle directory di destinazione è approssimativamente la stessa, allora srcfile verrà letto una sola volta dal disco. Il resto del tempo verrà letto dalla cache.

Lo renderei un po 'più generale, quindi otterrai anche i sottodir:

for x in dest1 dest2 dest3; do cp -a srcdir $x &; done; wait;

Se la velocità di scrittura delle directory dest è molto diversa (ad esempio, una è su un disco ram e l'altra su NFS), è possibile che le parti di srcdir vengano lette durante la copia di srcdir in dest1 non si trovino più nella cache del disco durante la scrittura dest2.


1

Secondo questa risposta: /superuser//a/1064516/702806

Una soluzione migliore è usare tare tee. Il comando è più complicato ma tarsembra essere molto potente per il trasferimento E deve leggere la fonte solo una volta.

tar -c /source/dirA/ /source/file1 | tee >(cd /foo/destination3/; tar -x) >(cd /bar/destination2/; tar -x) >(cd /foobar/destination1/; tar -x) > /dev/null

Per usarlo in uno script, potrebbe essere necessario avviare lo script con bash -x script.sh


Divertente. Ho pensato "questo ha senso, avere un voto". Upvoted. Poi ho controllato il link ...: D
Kamil Maciorowski il

Questo è abbastanza chiaramente superiore alla risposta (accettata) di David Spillett se si copiano più file contemporaneamente. Per un singolo file sorgente, l'unico vantaggio che vedo nell'aggiunta tarè che copierà automaticamente (preserva) gli attributi del file (ad es. Data / ora di modifica, modalità (protezione) e potenzialmente ACL, proprietario / gruppo (se privilegiato), SELinux contesto (se applicabile), attributi estesi (se applicabile), ecc.) ... ... ... ... ... ... PS Perché l'utente dovrebbe utilizzare bash -x?
Scott,

Ho usato #!/bin/shall'inizio del mio script ma la sintassi del comando non è stata accettata. Puoi usare bash -xo #!/bin/bashall'inizio del tuo file. Non so perché ci sia una differenza tra she bashinterpretazioni.
Rémi Girard,

Kamil Maciorowski - Non so perché la tua risposta non sia stata votata. È la soluzione perfetta Volevo condividerlo.
Rémi Girard,

0

In bash:

for x in dest1 dest2 dest3; do cp srcfile $x &>/dev/null &; done; wait;

2
non penso che questo funzionerà bene. in una copia idealmente parallela che leggeresti una volta, scrivendo molte volte. penso che questo farà 1: 1 legge: scrive. forse se le copie iniziano abbastanza velocemente e la cache dell'unità è abbastanza grande, non sarà necessario cercare le testine di lettura.
Quack Quixote

0

Se vuoi farlo in Windows da PowerShell, non è possibile per impostazione predefinita, perché a differenza -Pathdell'argomento, -Destinationnon accetta più argomenti. Tuttavia, è possibile utilizzare -Passthroughe collegare a catena i comandi. (Ma non è divertente.)

La soluzione migliore è crearne una tua, come mostrato qui .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.