Utilizo el siguiente script bash para copiar solo archivos de cierta extensión (en este caso * .sh), sin embargo, todavía copia todos los archivos. que esta mal
desde = $ 1 a = $ 2 rsync -zarv --include = "*. sh" $ de $ a
Creo que --include
se utiliza para incluir un subconjunto de archivos que de otro modo están excluidos por --exclude
, en lugar de incluir solo esos archivos. En otras palabras: tienes que pensar en incluir el significado de no excluir .
Prueba en su lugar:
rsync -zarv --include "*/" --exclude="*" --include="*.sh" "$from" "$to"
Para rsync versión 3.0.6 o superior, el orden debe modificarse de la siguiente manera (ver comentarios):
rsync -zarv --include="*/" --include="*.sh" --exclude="*" "$from" "$to"
Agregar la -m
bandera evitará crear estructuras de directorio vacías en el destino. Probado en la versión 3.1.2.
Entonces, si solo queremos archivos * .sh, tenemos que excluir todos los archivos --exclude="*"
, incluir 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 patrón de la página de manual
rsync -zarv --include="*/" --include="*.sh" --exclude="*" "$from" "$to"
.
--include=\*.sh
entonces --exclude=\*
)
La respuesta de @chepner copiará todos los subdirectorios independientemente del hecho de que contenga el archivo o no. Si necesita excluir los subdirectorios que no contienen el archivo y aún conservan la estructura del directorio, use
rsync -zarv --prune-empty-dirs --include "*/" --include="*.sh" --exclude="*" "$from" "$to"
Una adición más: si necesita sincronizar archivos por sus extensiones en un solo directorio (sin recursividad), debe usar una construcción como esta:
rsync -auzv --include './' --include '*.ext' --exclude '*' /source/dir/ /destination/dir/
Preste atención al punto en el primero --include
. --no-r
no funciona en esta construcción.
EDITAR:
¡Gracias a gbyte.co por el valioso comentario!
include
y las exclude
opciones en el orden que se especificaron en. Además de esto, se detiene en la primera emparejado. Entonces, si especificamos --exclude '*'
en el primer lugar en este ejemplo, rsync no hará nada. Consulte al hombre para obtener más explicaciones.
-- include './'
dice ¿incluir todo en la ruta del directorio de origen? Luego, el siguiente `--include '.ext'` incluye el archivo específico en la ruta de origen nombrada .ext
y luego la exclusión dice no enviar nada más --exclude '*'
. ¿Es eso correcto?
--include '*.ext'
y no--include '.ext'
Aquí está la parte importante de la página de manual:
A medida que se crea la lista de archivos / directorios para transferir, rsync verifica cada nombre que se transferirá con la lista de patrones de inclusión / exclusión por turno, y se actúa sobre el primer patrón coincidente: si es un patrón de exclusión, entonces ese archivo es omitido si es un patrón de inclusión, entonces ese nombre de archivo no se omite; si no se encuentra un patrón coincidente, no se omite el nombre del archivo.
Para resumir:
Además, algo que termina con una barra es un directorio coincidente (como lo find -type d
haría).
Separemos esta respuesta de arriba.
rsync -zarv --prune-empty-dirs --include "*/" --include="*.sh" --exclude="*" "$from" "$to"
.sh
archivoFinalmente, --prune-empty-directories
evita que la primera regla genere directorios vacíos por todas partes.
Si alguien busca esto ... Quería rsync solo archivos y carpetas específicos y logré hacerlo con este comando: rsync --include-from=rsync-files
Con archivos rsync:
my-dir/
my-file.txt
- /*
Escribí esta práctica función y puse mis scripts bash o ~/.bash_aliases
. Probado la sincronización local en Linux con bash e awk
instalado. Funciona
selrsync(){
# selective rsync to sync only certain filetypes;
# based on: https://stackoverflow.com/a/11111793/588867
# Example: selrsync 'tsv,csv' ./source ./target --dry-run
types="$1"; shift; #accepts comma separated list of types. Must be the first argument.
includes=$(echo $types| awk -F',' \
'BEGIN{OFS=" ";}
{
for (i = 1; i <= NF; i++ ) { if (length($i) > 0) $i="--include=*."$i; } print
}')
restargs="$@"
echo Command: rsync -avz --prune-empty-dirs --include="*/" $includes --exclude="*" "$restargs"
eval rsync -avz --prune-empty-dirs --include="*/" "$includes" --exclude="*" $restargs
}
corto, útil y extensible cuando se quiere agregar más argumentos (es decir --dry-run
).
selrsync 'tsv,csv' ./source ./target --dry-run
rsync
, esto se puede lograr muy bien con los componentes internos del shell?