Cópia paralela de arquivo de fonte única para múltiplos destinos?

14

Eu tenho vários arquivos grandes em mídia ótica que gostaria de copiar para vários destinos - neste caso, tenho dois discos rígidos conectados ao mesmo computador. Existe um utilitário que pode funcionar como:

copy source target1 target2 ... targetN
    
por Goyuix 31.08.2009 / 03:25

7 respostas

22

Para arquivos únicos, você pode usar tee para copiar para vários lugares:

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

ou se preferir a versão demoggada:

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

Observe que, como Dennis aponta nos comentários, tee produz para stdout , bem como os arquivos listados, portanto, usa redirecionamento para apontar para o arquivo 3 nos exemplos acima. Você também pode redirecionar isso para /dev/null como abaixo - isso tem a vantagem de manter a lista de arquivos mais consistente na linha de comando (o que pode facilitar a criação de uma solução para um número variável de arquivos), mas é um pouco menos eficiente (embora a diferença de eficiência seja pequena: aproximadamente igual à diferença entre usar a versão cat ou a versão sem cat ):

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

Você provavelmente poderia combinar um dos itens acima com find facilmente para operar em vários arquivos em um diretório e menos facilmente para operar em arquivos espalhados por uma estrutura de diretórios. Caso contrário, talvez seja necessário definir as várias operações de cópia em paralelo como tarefas separadas e esperar que o cache de disco do SO seja brilhante e / ou grande o suficiente para que cada uma das tarefas paralelas tenha dados de leitura armazenados em cache em vez de causar problemas. debatendo-se.

DISPONIBILIDADE: tee é comumente disponível em configurações padrão do Linux e outros sistemas unix ou unix-like, geralmente como parte do pacote GNU "coreutils". Se você estiver usando o Windows (sua pergunta não especifica), você deverá encontrá-lo nas várias portas do Windows, como o Cygwin.

INFORMAÇÕES SOBRE PROGRESSO: Como a cópia de um arquivo grande em uma mídia ótica pode levar algum tempo (ou em redes lentas, ou em um arquivo ainda maior, mesmo a partir de mídia rápida local), informações de progresso podem ser úteis. Na linha de comando, costumo usar o visualizador de canais (disponível na maioria das distribuições de Linux e muitas coleções de portas do Windows e fácil para compilar a si mesmo onde não estiver disponível diretamente) para isso - basta substituir cat por pv da seguinte forma:

pv <inputfile> | tee <outfile1> <outfile2> > <outfile3>
    
por 31.08.2009 / 03:33
5

No Windows:

n2ncopy fará isso:

ParaLinux:

Ocomandocpsozinhopodecopiardeváriasfontes,masinfelizmentenãodeváriosdestinos.Vocêprecisaráexecutá-lováriasvezesemumloopdealgumtipo.Vocêpodeusarumloopcomoesseecolocartodososnomesdediretórioemumarquivo:

OLDIFS=$IFSIFS=$'\n'forlinein$(catfile.txt):docpfile$linedoneIFS=$OLDIFS

ouusexargs:

echodir1dir2dir3|xargs-n1cpfile1

Ambospermitemcopiardiretóriosinteiros/múltiplosarquivos.Issotambémédiscutidoem Artigo do StackOverflow.

    
por 31.08.2009 / 03:34
4

Com base na resposta dada para uma pergunta semelhante Outra maneira é usar GNU Parallel para executar várias instâncias de cp de uma só vez:

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

O comando acima copia o arquivo1 para todas as três pastas de destino em paralelo

    
por 01.07.2014 / 06:06
2

No bash (Linux, Mac ou Cygwin):

cat source | tee target1 target2 >targetN

(tee copia sua entrada para STDOUT, então use o redirecionamento no último alvo).

No Windows, o Cygwin é muitas vezes exagerado. Em vez disso, você pode simplesmente adicionar os exes do projeto UnxUtils , que inclui cat, tee e muitos outros.

    
por 26.10.2010 / 08:50
1

Solução de Ryan Thompson:

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

faz muito sentido: se a velocidade de gravação dos diretórios de destino for aproximadamente a mesma, então o srcfile só será lido uma vez do disco. O resto do tempo será lido no cache.

Eu faria um pouco mais geral, então você também terá subdirs:

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

Se a velocidade de gravação dos dirs de destino for muito diferente (por exemplo, um está em um disco de RAM e outro no NFS), você poderá ver que as partes de srcdir lidas ao copiar srcdir para dest1 não estão mais no disco cache ao escrever dest2.

    
por 27.07.2010 / 12:08
1

De acordo com esta resposta: link

Uma solução melhor é usar tar e tee . O comando é mais complicado, mas tar parece ser muito poderoso para transferência E precisa ler a fonte apenas uma 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 usá-lo em um script, talvez seja necessário iniciar seu script com bash -x script.sh

    
por 10.04.2017 / 18:36
0

No bash:

for x in dest1 dest2 dest3; do cp srcfile $x &>/dev/null &; done; wait;
    
por 04.10.2009 / 23:36