Como copiar dois diretórios? [duplicado]

83

Eu tenho duas imagens de diretórios e imagens2 com essa estrutura no Linux:

/images/ad  
/images/fe  
/images/foo  

... e outras 4000 pastas

e o outro é como:

/images2/ad  
/images2/fe  
/images2/foo

... e outras 4000 pastas

Cada uma dessas pastas contém imagens e os nomes dos diretórios em imagens e imagens2 são exatamente os mesmos, mas seu conteúdo é diferente. Então eu quero saber como eu posso copiar as imagens de / images2 / ad em imagens / anúncios, as imagens de / images2 / foo em images / foo e assim por diante com todas as 4000 pastas.

    
por ssierral 13.08.2014 / 00:59

4 respostas

127

Este é um trabalho para o rsync . Não há nenhum benefício em fazer isso manualmente com um loop de shell, a menos que você queira mover o arquivo em vez de copiá-lo.

rsync -a /images/ /images2/

(Anote a barra no final em images , caso contrário, copie para /images2/images .)

Se houver imagens com o mesmo nome nos dois diretórios, o comando acima sobrescreverá /images2/SOMEPATH/SOMEFILE com /images/SOMEPATH/SOMEFILE . Se você quiser substituir apenas arquivos mais antigos, adicione a opção -u . Se você quiser manter sempre a versão em /images2 , adicione a opção --ignore-existing .

Se você quiser mover os arquivos de /images , com rsync, poderá passar a opção --remove-source-files . Em seguida, o rsync copia todos os arquivos por vez e remove cada arquivo quando é feito. Isso é muito mais lento do que mover se os diretórios de origem e destino estiverem no mesmo sistema de arquivos.

    
por 13.08.2014 / 02:41
33

A melhor escolha, como já foi postada, é o rsync. No entanto, também uníssono seria um excelente software para fazer este trabalho. Ambos podem ser usados em vários sistemas operacionais.

Rsync

O rsync sincroniza em uma direção da origem ao destino. Portanto, a seguinte declaração

rsync -avh --progress Source Destination

sincroniza tudo, de Origem a Destino . A pasta mesclada reside em Destino .

-a significa "arquivar" e copia tudo de forma recursiva da origem para o destino, preservando quase tudo.

-v fornece mais resultados ("verbose").

-h para legibilidade humana.

- progresso para mostrar quanto trabalho é feito.

Se você quiser apenas atualizar a pasta destino com arquivos mais recentes da pasta de origem:

rsync -avhu --progress source destination

Uníssono

o sincronismo é sincronizado nas duas direções. Portanto, a seguinte declaração

unison Source Destination

sincroniza os dois diretórios em ambas as direções e, finalmente, a fonte é igual a destino. É como fazer o rsync duas vezes da origem para o destino e vice-versa.

Para usos mais avançados, consulte as páginas do manual ou os seguintes sites:

  1. link
  2. link
por 04.02.2016 / 01:12
4
for dir in images2/*; do mv "$dir"/* "images/$(basename "$dir")"; done

Faça um loop sobre todo o conteúdo de images2 usando um glob expandido (para evitar os problemas de análise de ls ) e então mv o conteúdo desses itens para a entrada correspondente em images . Usa basename para remover os images2 do caminho globbed.

    
por 13.08.2014 / 01:57
1

@ inulinux12, você pode usar a seguinte linha de uma linha for loop da linha de comando:

$ for dir in images2/*; do mv "$dir"/* "${dir/2/}"; done

Isso moverá todos os arquivos de images2 para images em seus respectivos diretórios. Nota: isso pressupõe que nenhum arquivo tenha o mesmo nome.

Por exemplo:

Antes da execução:

$ ls -R images*
images:
ad  adfoo  fe
images/ad:
jpg.1  jpg.2
images/adfoo:
jpg.7
images/fe:
jpg.5
images2:
ad  adfoo  fe
images2/ad:
jpg.3
images2/adfoo:
jpg.6
images2/fe:
jpg.4

Após a execução:

$ ls -R images*
images:
ad  adfoo  fe
images/ad:
jpg.1  jpg.2  jpg.3
images/adfoo:
jpg.6  jpg.7
images/fe:
jpg.4  jpg.5

Espero que isso ajude.

    
por 13.08.2014 / 01:23