Rsync, incluye solo ciertos tipos de archivos, excluyendo algunos directorios

14

Quiero sincronizar solo ciertos tipos de archivos (por ejemplo .py) y quiero excluir archivos en algunos directorios (por ejemplo venv).

Esto es lo que he intentado:

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

Pero no funciona.

¿Qué me estoy perdiendo?

También seguí la respuesta a esta pregunta pero no ayudó.

CentAu
fuente
¿Por qué necesitas la inicial --include='*/'?
Charlie Parker
1
¿Cómo se crea el comando si tengo directorios recursivos a los que quiero enviar solo un tipo de archivo? Parece que solo lo hace para el directorio de destino probablemente debido a la última exclusión que excluye todo
Charlie Parker

Respuestas:

17

venv/debe excluirse antes de */ incluirlo:

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

La sutileza es que rsyncprocesa las reglas en orden y gana la primera regla coincidente. Entonces, si --include='*/'es antes --exclude='venv/', entonces el directorio venv/está incluido por --include='*/'y la regla de exclusión nunca es consultada.

¿Podríamos simplificar esto?

¿Por qué necesitamos --include='*/'y --exclude='*'? ¿Por qué no es --exclude=venv/ --include='*.py'suficiente?

El valor predeterminado es incluir archivos / directorios. Entonces, considere:

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

Esto incluiría todo excepto archivos o directorios debajo venv/. Sin embargo, solo quieres .pyarchivos. Eso significa que tenemos que excluir explícitamente otros archivos con --exclude='*'.

--exclude='*'excluye tanto archivos como directorios. Entonces, si especificamos --exclude='*', todos los directorios se excluirían y solo se encontrarían los .pyarchivos en el directorio raíz. .pylos archivos en subdirectorios nunca se encontrarían porque rsyncno busca en directorios que están excluidos. Por lo tanto, si lo hemos hecho --exclude='*', debemos precederlo --include='*/'para garantizar que se exploren los contenidos de todos los directorios.

John1024
fuente
¡Excelente! ¡Gracias! Solo para mi comprensión, ¿por qué necesitamos --include='*/'y --exclude='*'? ¿Por qué solo --exclude=venv/ --include='*.py'no funciona?
CentAu
1
@CentAu Acabo de actualizar la respuesta con una discusión sobre eso.
John1024
¿Cómo se crea el comando si tengo directorios recursivos a los que quiero enviar solo un tipo de archivo? Parece que solo lo hace para el directorio de destino probablemente debido a la última exclusión que excluye todo.
Charlie Parker
1
Marcadores! Especialmente por la sutileza. ¡No puedo pensar en ninguna otra utilidad de CLI donde el orden de las banderas sea importante !
Antortjim