compara 2 diretórios e copie as diferenças em um terceiro diretório

27

Executando o Ubuntu 12.04, eu quero comparar dois diretórios, digamos pasta1 / e pasta2 / e copie todos os arquivos que são diferentes para folder3 /. Há também arquivos aninhados, então os subdiretórios correspondentes também devem ser copiados

Existe um único comando que me ajudaria? Eu posso obter a lista completa de arquivos alterados em execução:

rsync -rcnC --out-format="%f" folder1/ folder2/

Mas o rsync não parece ter a capacidade de "exportar" esses arquivos em um diretório de destino diferente. Posso canalizar a lista para cp ou algum outro programa, para que os arquivos sejam copiados, enquanto os diretórios também são criados? Por exemplo, tentei

rsync -rcnC --out-format="%f" folder1/ folder2/ | xargs cp -t folder3/

mas isso também não preservaria diretórios, ele simplesmente copiaria todos os arquivos dentro de folder3 /

    
por periklis 08.05.2013 / 14:50

3 respostas

32

Use --compare-dest.

Da página do manual:

--compare-dest=DIR - This option instructs rsync to use DIR on the destination machine as an additional hierarchy to compare destination files against doing transfers (if the files are missing in the destination directory). If a file is found in DIR that is identical to the sender's file, the file will NOT be transferred to the destination directory. This is useful for creating a sparse backup of just files that have changed from an earlier backup.

primeiro verifique sua sintaxe com --dry-run

rsync -aHxv --progress --dry-run --compare-dest=folder2/ folder1/ folder3/

Então, quando você estiver satisfeito com a saída:

rsync -aHxv --progress  --compare-dest=folder2/ folder1/ folder3/

Este link tem uma boa explicação do escopo --compare-dest.

    
por 16.05.2013 / 15:17
3

Este pequeno script deve funcionar:

folder1="firsts_folder/"
folder2="second_folder/"
folder3="target_folder"
for x in 'rsync -rcnC --out-format="%n"  $folder1 $folder2'
    do
        if [ -d "$folder1/$x" ]; then
            mkdir -p "$folder3/$x"
        else
            cp -frv $folder1/$x $folder3/$x
        fi
done

Mas também acho que a saída de parsing do diff -qr seria uma solução melhor, pois fornece caminho e nome para cada arquivo de forma consistente.

EDITAR

Este seria um comando, seu comando ligeiramente modificado. Mas isso criará folder1 sob o folder3 . E isso não funciona com caminhos completos, mas também o script acima não funciona com caminhos completos.

rsync -rcnC --out-format="\"%f\"" folder1/ folder2/ | xargs cp --parents -rfvt folder3/

Eu usei \" em rsync para fazê-lo funcionar com arquivos e diretórios contendo espaços em branco. Testado no Ubuntu 10.04. Espero que ajude.

    
por 08.05.2013 / 17:16
2
rsync -rcnC --out-format="%f" . ../folder2/ |xargs cp --parents -rt ../folder3/

Essa é a forma mais simples que eu poderia criar, se você estiver disposto a primeiro descer em folder1 antes de emitir o comando.

Esta é a opção mais lenta , mas acredito que atenda aos seus requisitos e pode ser executada usando nomes de diretório não relativos:

rsync -rcnC --out-format="%n" folder1/ folder2/ |grep -vP "/$" |xargs -I{} rsync -R folder1/./{} folder3/

Eu deixei seu comando rsync original sozinho, porque você disse que estava lhe dando a lista de arquivos correta (e meus arquivos de teste são obviamente diferentes dos seus, então eu não poderia dizer com certeza que eu estaria recebendo o lista de arquivos correta se eu mexi com ele).

O grep está lá para remover nomes de diretório da saída de rsync .

A saída de grep é então canalizada para outro rsync usando xargs . No parâmetro folder1/./{} , o extra ./ é usado para informar ao rsync para criar os diretórios relativos começando com ./{} , ignorando folder1/ . Em outras palavras, evita criar folder3/folder1/ .

Eu só pude testar isso no CentOS 6.4, mas o AFAIK deve funcionar da mesma forma no Ubuntu 12.04.

EDIT: Devo notar que a resposta do smithian é sem dúvida melhor, mas eu queria tentar fazer isso com seu comando rsync original no tato desde que estava dando a saída desejada.

    
por 17.05.2013 / 00:24