Respostas:
Para arquivos únicos, você pode usar tee
para copiar para vários locais:
cat <inputfile> | tee <outfile1> <outfile2> > <outfile3>
ou se você preferir a versão desmoggificada:
tee <outfile1> <outfile2> > <outfile3> < <inputfile>
Nota que, como aponta Dennis nos comentários tee
saídas para stdout
, bem como os arquivos listados, portanto, usando redirecionamento para apontar para arquivo 3 nos exemplos acima. Você também pode redirecioná-lo para /dev/null
o seguinte: isso tem a vantagem de manter a lista de arquivos mais consistente na linha de comando (o que pode facilitar a criação de scripts de uma solução para números variáveis de arquivos), mas é um pouco menos eficiente (embora o a diferença de eficiência é pequena: aproximadamente a mesma diferença entre usar a cat
versão ou a versão sem cat
):
cat <inputfile> | tee <outfile1> <outfile2> <outfile3> > /dev/null
Provavelmente, você pode combinar um dos itens acima com find
bastante facilidade para operar em vários arquivos em um diretório e menos facilmente com arquivos espalhados por uma estrutura de diretórios. Caso contrário, talvez seja necessário desativar as várias operações de cópia em paralelo como tarefas separadas e esperar que o cache do disco do sistema operacional seja brilhante e / ou grande o suficiente para que cada uma das tarefas paralelas usasse dados de leitura em cache desde o início, em vez de causar a cabeça da unidade se debatendo.
DISPONIBILIDADE: tee
normalmente está disponível nas configurações padrão do Linux e em outros sistemas unix ou unix, geralmente como parte do pacote "coreutils" do GNU. Se você estiver usando o Windows (sua pergunta não especifica), você deve encontrá-lo nas várias portas do Windows, como o Cygwin.
INFORMAÇÃO DE PROGRESSO: Como copiar um arquivo grande da mídia óptica pode levar algum tempo (ou em rede lenta ou um arquivo ainda maior a partir da mídia rápida local), as informações do progresso podem ser úteis. Na linha de comando que tendem a usar visualizador de tubo (disponível na maioria das distribuições Linux e muitas coleções porta do Windows e fácil de compilar-se onde não disponível diretamente) para isso - basta substituir cat
com pv
assim:
pv <inputfile> | tee <outfile1> <outfile2> > <outfile3>
tee
saída também será stdout, portanto, você pode fazer isso, tee outputfile1 outputfile2 < inputfile > /dev/null
pois a saída de um arquivo binário para o terminal pode ser barulhenta e interferir nas configurações.
tar cf - file1 file2 | tee >(tar xf - -C ouput1) | tar xf - -C output2
Para Windows:
O n2ncopy fará o seguinte:
Para Linux:
O cp
comando só pode copiar a partir de várias fontes, mas, infelizmente, não vários destinos. Você precisará executá-lo várias vezes em um loop de algum tipo. Você pode usar um loop assim e colocar todos os nomes de diretório em um arquivo:
OLDIFS=$IFS
IFS=$'\n'
for line in $(cat file.txt):
do
cp file $line
done
IFS=$OLDIFS
ou use xargs:
echo dir1 dir2 dir3 | xargs -n 1 cp file1
Ambos permitem copiar diretórios inteiros / vários arquivos. Isso também é discutido neste artigo StackOverflow.
Baseado na resposta dada a uma pergunta semelhante Outra maneira é usar o GNU Parallel para executar várias cp
instâncias ao mesmo tempo:
parallel -j 0 -N 1 cp file1 ::: Destination1 Destination2 Destination3
O comando acima copiará o arquivo1 para todas as três pastas de destino em paralelo
No bash (Linux, Mac ou Cygwin):
cat source | tee target1 target2 >targetN
(tee copia sua entrada para STDOUT, portanto, use o redirecionamento no último destino).
No Windows, o Cygwin costuma ser um exagero. Em vez disso, você pode adicionar os exes do projeto UnxUtils , que incluem gato, camiseta e muitos outros.
A 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, o srcfile será lido apenas uma vez no disco. O restante do tempo será lido do cache.
Eu o tornaria um pouco mais geral, para que você também tenha subdiretórios:
for x in dest1 dest2 dest3; do cp -a srcdir $x &; done; wait;
Se a velocidade de gravação dos diretórios de destino for muito diferente (por exemplo, um está em um disco ram e o outro no NFS), você poderá ver que as partes do srcdir lidas ao copiar o srcdir para dest1 não estão mais no cache do disco durante a gravação dest2.
De acordo com esta resposta: /superuser//a/1064516/702806
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, pode ser necessário iniciar seu script com bash -x script.sh
tar
é que ele copia (preserva) automaticamente os atributos do arquivo (por exemplo, data / hora da modificação, modo (proteção) e potencialmente ACLs, proprietário / grupo (se privilegiado), SELinux contexto (se aplicável), atributos estendidos (se aplicável), etc.)……………… PS Por que o usuário precisaria usar bash -x
?
#!/bin/sh
no início do meu script, mas a sintaxe do comando não é aceita. Você pode usar bash -x
ou #!/bin/bash
no início do seu arquivo. Não sei por que há uma diferença entre sh
e bash
interpretações.
Na festança:
for x in dest1 dest2 dest3; do cp srcfile $x &>/dev/null &; done; wait;
Se você deseja fazer isso no Windows a partir do PowerShell, não é possível por padrão, porque, diferentemente do -Path
argumento, -Destination
ele não recebe vários argumentos. No entanto, você pode usar -Passthrough
e encadear os comandos. (Mas isso não é divertido.)
A melhor solução é criar o seu, como é mostrado aqui .