Aquí está la parte importante de la página man:
A medida que se construye la lista de archivos/directorios para transferir, rsync verifica cada nombre que se transferirá contra la lista de patrones de inclusión/exclusión, y se actúa sobre el primer patrón coincidente:si es un patrón de exclusión, entonces ese archivo es saltado; si es un patrón de inclusión, ese nombre de archivo no se omite; si no se encuentra un patrón coincidente, entonces el nombre del archivo no se omite.
Para resumir:
- ¡Si no coincide con ningún patrón, se copiará un archivo!
- El algoritmo se cierra una vez que cualquier patrón coincide
Además, algo que termina con una barra inclinada es directorios coincidentes (como find -type d
lo haría).
Separemos esta respuesta de arriba.
rsync -zarv --prune-empty-dirs --include "*/" --include="*.sh" --exclude="*" "$from" "$to"
- No omita ningún directorio
- No te saltes ningún
.sh
archivos - Omitir todo
- (Implicítamente, no omita nada, pero la regla anterior evita que se cumpla la regla predeterminada).
Finalmente, el --prune-empty-directories
evita que la primera regla genere directorios vacíos por todas partes.
Creo que --include
se utiliza para incluir un subconjunto de archivos que de otro modo estarían excluidos por --exclude
, en lugar de incluir solo esos archivos. En otras palabras:debe pensar en incluir lo que significa no excluir .
Prueba en su lugar:
rsync -zarv --include "*/" --exclude="*" --include="*.sh" "$from" "$to"
Para la versión 3.0.6 o superior de rsync, el orden debe modificarse de la siguiente manera (ver comentarios):
rsync -zarv --include="*/" --include="*.sh" --exclude="*" "$from" "$to"
Agregando el -m
flag evitará crear estructuras de directorios vacías en el destino. Probado en la versión 3.1.2.
Entonces, si solo queremos archivos *.sh, debemos excluir todos los archivos --exclude="*"
, incluye todos los directorios --include="*/"
e incluir todos los archivos *.sh --include="*.sh"
.
Puede encontrar algunos buenos ejemplos en la sección Incluir/Excluir reglas de patrones de la página del manual
Una adición más:si necesita sincronizar archivos por sus extensiones en solo un directorio (sin recursividad) deberías usar una construcción como esta:
rsync -auzv --include './' --include '*.ext' --exclude '*' /source/dir/ /destination/dir/
Presta atención al punto en el primer --include
. --no-r
no funciona en esta construcción.
EDITAR:
¡Gracias a gbyte.co por el valioso comentario!
EDITAR:
El -uzv
las banderas no están relacionadas directamente con esta pregunta, pero las incluí porque las uso habitualmente.
La respuesta de @chepner copiará todos los subdirectorios, ya sea que contenga archivos o no. Si necesita excluir los subdirectorios que no contienen el archivo y aun así conservar la estructura del directorio, use
rsync -zarv --prune-empty-dirs --include "*/" --include="*.sh" --exclude="*" "$from" "$to"