Sincronizando arquivos com rsync apenas por nomes de arquivos, ignore diretórios

3

Estou tentando sincronizar arquivos do Sistema A para o Sistema B. No entanto, os arquivos são reorganizados em outra estrutura de diretório, o que torna o uso do rsync difícil.

Existe alguma maneira de dizer ao rsync para ignorar diretórios e operar apenas com nomes de arquivos? Os nomes dos arquivos são únicos - os diretórios não são. A estrutura de diretórios não é fixa, então não posso simplesmente substituí-los. Eu já pensei em escrever um script que retira as informações do diretório, mas não tenho certeza se isso traz outros problemas.

Na verdade, sim, desejo nivelar a estrutura de diretórios. Dadas as respostas, o rsync provavelmente não é o que desejo usar.

Estou trabalhando com vídeos, terceiros criam uma estrutura de diretórios (e eles devem poder alterar a estrutura de diretórios sempre que apropriado). Esses vídeos precisam ser sincronizados com um sistema de arquivos mestre. Os nomes dos arquivos são aceitos para não serem alterados. Então, algo como um diff entre "find. | Rip-out-path" em ambos os sistemas e um diff pode fazer o truque; mas eu queria saber se o rsync tinha algum sinalizador mágico para ignorar diretórios quando recursing - semelhante ao parâmetro -p no patch.

    
por Felicitus 27.07.2011 / 20:21

10 respostas

1

Você está ferrado, ou menos. Enquanto você pode dizer a rsync para recursar e todos os tipos de outros jogos, você não pode dizer para ir caçar em uma árvore de sistema de arquivos para encontrar um arquivo com o mesmo nome do outro lado.

Eu diria que o que você terá que fazer é ter um pequeno script de wrapper no final que, dado um arquivo simples, retorna o caminho completo para o arquivo nesse ponto e, em seguida, iterar através de cada arquivo no final local, chamando este script wrapper para obter o caminho remoto e, em seguida, executando rsync one ... file ... at ... a ... time ...

Isto, é claro, assumindo que todos os arquivos já existam no outro extremo ... onde eles são colocados se não estiverem lá? Eles são ignorados?

Eu encontraria quem criou esse esquema de armazenamento de arquivos maluco e quebre seus dedos.

    
por 28.07.2011 / 00:54
1

Provavelmente, a maneira mais simples de resolver a movimentação de todos os arquivos da árvore de diretórios para um único diretamente seria usando find com as opções -type e -exec. A opção -type limita a saída a um tipo específico de entrada de diretório (f para arquivo, d para diretório, etc.). A opção -exec passa o nome encontrado (como {}) para uma linha de comando com opções.

Seguem alguns exemplos:

find /directory/top/ -type f -exec rsync {} desthost:/destdir 

find /directory/top/ -type f -exec scp {} desthost:/destdir 
    
por 30.07.2011 / 20:43
1
SOURCE_DIR=/path/to/lots/of/dirs/and/files
LINK_PATH=/path/to/store/all/files/as/symlinks/in/single/directory
DEST_PATH=/path/to/place/all/files/in/single/directory/with/no/child/directories

find $SOURCE_DIR -type f -print0 | xargs -0 cp -s --target-directory=$LINK_PATH
rsync -Lts $LINK_PATH/* $USER@$DEST_IP:$DEST_PATH
    
por 22.01.2014 / 15:52
0

e a opção --fuzzy no rsync? Eu não sei se isso funcionaria no seu caso, mas você poderia tentar.

    
por 28.07.2011 / 12:35
0

Ainda estou mantendo a minha outra resposta "no dedo" no caso geral, mas tenho uma solução diferente para a sua situação específica, que é, como eu a entendo:

  • Outras pessoas têm sua própria cópia de material, na hierarquia maluca que escolherem; e
  • Você precisa de todos os arquivos deles, mas organizados em sua própria hierarquia de crackpot

O que eu estou pensando é que você execute um rsync em diretórios remotos específicos (como /storage/.remotes/client1/ , /storage/.remotes/client2/ , etc) para cada um dos sistemas de arquivos remotos que estiver sincronizando, e então tenha um script que normalize os nomes dos arquivos em sua própria hierarquia (supondo que você possa descrever algoritmicamente seu esquema organizacional), e que você execute tudo depois que o rsync tiver feito isso é symlink nos locais de armazenamento remoto específicos do cliente. Se você não pode descrever sua hierarquia desejada por algoritmos, então eu acho que você terá que fazer o seu symlinking manualmente (ou pelo menos com algum nível de entrada humana, mesmo que haja suporte de ferramenta).

A única dificuldade então é se o remoto reorganiza suas coisas, mas então você apenas detecta os links simbólicos quebrados, encontre os novos locais dos nomes dos arquivos (assumindo que os nomes não mudaram, apenas os locais).

    
por 28.07.2011 / 16:01
0

Se todos os arquivos estiverem no mesmo sistema de arquivos, pode ser mais fácil vinculá-los a um diretório no lado da origem e, em seguida, rsync aquele diretório. Algo como:

#!/bin/bash
set -e
mkdir flattened_dir
find sourcedir1 sourcedir2 sourcedir3 -type f -exec ln -t flattened_dir/ {} +
rsync -avP flattened_dir/ remote:destination/
rm -r flattened_dir

P.S. Se find não suportar + , você poderá usar \;

    
por 06.11.2012 / 18:05
0

Da mesma forma, eu queria extrair arquivos de diretórios e colocá-los em um único diretório simples usando apenas o nome do arquivo. A solução é:

 find /directory/top/ -type f -exec rsync -av 'basename {}' desthost:/destdir 

Você também pode usar alguns dos outros sinalizadores encontrados para limitar os arquivos desejados ... como talvez queira apenas os arquivos JPG:

 find /directory/top/ -type f -name "*.JPG" -exec rsync -av 'basename {}' desthost:/destdir 
    
por 22.09.2013 / 15:15
0

Você pode usar Bash globopt ( ** ) para corresponder cada arquivo recursivamente, conforme descrito em este post .

Como você está invocando o rsync apenas uma vez, ele deve ser muito mais rápido do que outras abordagens nas quais você invoca um comando para cada arquivo (como find ... -exec ).

    
por 01.12.2014 / 23:27
0

Você pode copiar arquivos de várias pastas de origem em uma pasta de destino (plana) sem transferir as subpastas de origem usando o comando:

find source_dir -name "*.pdf" >/tmp/xx.txt
rsync -t -v --no-relative --files-from=/tmp/xx.txt / desthost:/destdir
rm -f /tmp/xx.txt
    
por 05.02.2018 / 12:25
-1

Você poderia fazer um diretório de cada vez, se isso lhe der um bom tamanho de lote de arquivos em uma chamada de processo para o rsync. Então, algo como:

find . -type d | while read dir; do rsync -a $dir/* user@host:flatdir; done
    
por 04.01.2012 / 00:21

Tags