linux pastas de mesclagem: rsync?

13

Eu tenho duas cópias de uma pasta

src/
dest/

Eu quero mesclá-los, fazendo o seguinte:

Se um arquivo estiver apenas em src , eu quero que ele seja movido para dest

Se um arquivo estiver apenas em dest , quero ignorado o IE deixado em paz.

Se um arquivo estiver em e tiver conteúdo idêntico (IE, mesmo tamanho e data), exclua de src

Se um arquivo está em ambos e não tem conteúdo idêntico, deixe em src para que eu possa mesclá-los manualmente.

Apenas um número muito pequeno de arquivos (entre 0% e 5% do total de arquivos) deve estar nesta última categoria, mas não sei como separar o em ambos e o mesmo em ambos, mas diferentes .

Eu tentei descobrir como fazer isso com rsync , mas não adiantou até agora.

    
por David Oneill 23.11.2010 / 19:31

3 respostas

17

Eu só realizei testes de funcionalidade limitados, então, por favor, tenha cuidado com este comando (--dry-run):

rsync -avPr --ignore-existing --remove-source-files src/ dest

Por favor, note o trailing / como isso vai recursão em src em vez de copiar src em si, isso deve manter seus caminhos existentes.

Ao usar o sinalizador --ignore-existing em combinação com o sinalizador --remove-source-files, você excluirá apenas os arquivos de src que são sincronizados de src para dest, ou seja, arquivos que não existiam anteriormente em dest somente.

Para excluir arquivos não sincronizados, ou seja, aqueles que já existiam em dest / as em src /, você pode usar:

for file in 'find src/ -type f'; do diff $file 'echo $file | sed 's/src/dest/'' && rm $file || echo $file; done

ou

find src -type f -exec bash -c 'cmp -s "$0" "${0/#src/dest}" && rm "$0"' {} \;

se os nomes de arquivos puderem conter espaços em branco / novas linhas /… Com relação ao comentário de Gilles sobre personagens especiais, isso é certamente algo para se ter em mente e existem muitas soluções, a mais simples seria passar um -i para rm que irá avisar antes de toda deleção. Desde que src /, ou seu caminho pai, seja fornecido para localizar, no entanto, o caminho completo deve resultar em todos os nomes de arquivos sendo manipulados corretamente pelos comandos diff e rm sem aspas.

    
por 23.11.2010 / 19:47
6

uníssono é a ferramenta que você está procurando. Tente unison-gtk se você preferir um gui. Mas eu não acho que isso irá apagar arquivos similares: uníssono tente ter ambos os diretórios idênticos. No entanto, será fácil 1) identificar quais arquivos devem ser copiados; 2) quais precisam de mesclagem manual.

    
por 24.11.2010 / 15:13
2

O script a seguir deve fazer as coisas de forma razoável. Ele move arquivos da origem para o destino, nunca sobrescrevendo um arquivo e criando diretórios conforme necessário. Os arquivos de origem que possuem um arquivo diferente correspondente no destino são deixados sozinhos, assim como os arquivos que não são arquivos ou diretórios regulares (por exemplo, links simbólicos). Os arquivos restantes na origem são aqueles para os quais há um conflito. Cuidado, eu não testei nada.

cd src
find . -exec sh -c '
    set -- "/path/to/dest/$0"
    if [ -d "$0" ]; then #  the source is a directory 
      if ! [ -e "$1" ]; then
        mv -- "$0" "$1"  # move whole directory in one go
      fi
    elif ! [ -e "$0" ]; then  # the source doesn't exist after all
      :  # might happen if a whole directory was moved
    elif ! [ -e "$1" ]; then  # the destination doesn't exist
      mv -- "$0" "$1"
    elif [ -f "$1" ] && cmp -s -- "$0" "$1"; then  # identical files
      rm -- "$0"
    fi
  ' {} \;

Outra abordagem seria fazer uma montagem de união um diretório acima do outro, por exemplo, com funionfs ou unionfs-fuse .

    
por 24.11.2010 / 02:01