Rsync, inclua apenas certos tipos de arquivos, excluindo alguns diretórios

14

Eu quero sincronizar apenas certos tipos de arquivo (por exemplo .py) e quero excluir arquivos em alguns diretórios (por exemplo venv).

Isto é o que eu tentei:

rsync -avz --include='*/' --exclude='venv/' --include='*.py' --exclude='*' /tmp/src/ /tmp/dest/

Mas isso não funciona.

o que estou perdendo?

Também segui a resposta a esta pergunta, mas não ajudou.

CentAu
fonte
por que você precisa da inicial --include='*/'?
Charlie Parker
1
Como alguém cria o comando se eu tenho diretórios recursivos que desejo enviar apenas um tipo de arquivo. Parece que só faz isso para o diretório de destino, provavelmente por causa da última exclui que exclui tudo
Charlie Parker

Respostas:

17

venv/precisa ser excluído antes da */ inclusão:

rsync -avz --exclude='venv/' --include='*/' --include='*.py' --exclude='*' /tmp/src/ /tmp/dest/

A sutileza é que rsyncprocessa as regras em ordem e a primeira regra correspondente vence. Portanto, se --include='*/'for anterior --exclude='venv/', o diretório venv/será incluído --include='*/'e a regra de exclusão nunca será consultada.

Poderíamos simplificar isso?

Por que precisamos --include='*/'e --exclude='*'? Por que não é --exclude=venv/ --include='*.py'suficiente?

O padrão é incluir arquivos / diretórios. Então, considere:

rsync -avz --exclude='venv/' --include='*.py' source target

Isso incluiria tudo, exceto arquivos ou diretórios abaixo venv/. Você, no entanto, deseja apenas .pyarquivos. Isso significa que temos que excluir explicitamente outros arquivos com --exclude='*'.

--exclude='*'exclui ambos os arquivos e diretórios. Portanto, se especificarmos --exclude='*', todos os diretórios serão excluídos e apenas os .pyarquivos no diretório raiz serão encontrados. .pyos arquivos nos subdiretórios nunca seriam encontrados porque rsyncnão examinam diretórios que são excluídos. Assim, se tivermos --exclude='*', precisamos precedê-lo --include='*/'para garantir que o conteúdo de todos os diretórios seja explorado.

John1024
fonte
Ótimo! Obrigado! Apenas para minha compreensão, por que precisamos --include='*/'e --exclude='*'? Por que apenas --exclude=venv/ --include='*.py'não funciona?
CentAu 4/09/16
1
@CentAu Acabei de atualizar a resposta com uma discussão sobre isso.
precisa saber é o seguinte
Como alguém cria o comando se eu tenho diretórios recursivos que desejo enviar apenas um tipo de arquivo. Parece que apenas o faz para o diretório de destino, provavelmente por causa da última exclusão que exclui tudo.
Charlie Parker
1
Favoritos! Especialmente pela sutileza. Não consigo pensar em nenhum outro utilitário CLI onde a ordem dos sinalizadores seja importante !
antortjim 24/03