rsync copia solo sobre ciertos tipos de archivos usando la opción incluir
110
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
Si bien no está estrictamente hablando, sugeriría citar $ from / $ to. No hacerlo puede darle resultados inesperados si los argumentos posicionales 1/2 incluyen espacios.
Kjetil Joergensen
¿Entendiste por qué tu comando no funcionaría?
Charlie Parker
@CharlieParker: ¿Tiene que usar rsync, esto se puede lograr muy bien con los componentes internos del shell?
Inian
Lo que esta pregunta y sus respuestas también carecen es cómo crear el comando si tengo directorios recursivos que quiero enviar solo un tipo de archivo. Parece que solo lo hace para el directorio de destino ...
Charlie Parker
Respuestas:
198
Creo que --includese 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 .
Agregar la -mbandera 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
Si bien obtendrá todos los subdirectorios, si hay archivos .sh en los subdirectorios que desea sincronizar, es probable que también desee usar --include = "* /".
Kjetil Joergensen
50
Probé esto en rsync versión 3.0.7, que obtuve hace mucho tiempo de macports, y no funcionó con este orden de incluye / excluye. Esto es lo que terminó con la que trabajó para mí (adaptada para OP): rsync -zarv --include="*/" --include="*.sh" --exclude="*" "$from" "$to".
Bijou Trouvaille,
3
Intenté con rsync 3.0.9 y no funcionó. Bijou tiene razón, el orden no es correcto (primero --include=\*.shentonces --exclude=\*)
TrueY
3
Tenga en cuenta que siempre puede hacer clic en editar y sugerir una edición a la respuesta :)
Achal Dave
2
No funciona con su pedido de incluye / excluye, pero funciona con el pedido sugerido por Bijou Trouvaille
John Smith Opcional
56
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
Este era un requisito para mí: "Si necesita excluir los subdirectorios que no contienen el archivo y aún conservan la estructura del directorio" +1
Juuso Ohtonen
1
No entiendo, ¿cómo supiste cuál era el orden de los --incluidos?
Charlie Parker
1
¿Cómo se crea el comando si tengo directorios recursivos que quiero enviar solo un tipo de archivo? Parece que solo lo hace para el directorio de destino.
Charlie Parker
15
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:
¿Cómo supiste cuál debía ser el orden de las banderas y qué debían incluir?
Charlie Parker
1
@CharlieParker, porque el rsync utiliza el includey las excludeopciones 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.
Serge Roussak
¿Me puedes explicar qué hace cada bandera? La primera bandera -- 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 .exty luego la exclusión dice no enviar nada más --exclude '*'. ¿Es eso correcto?
Charlie Parker
1
¿Cómo se crea el comando si tengo directorios recursivos que quiero enviar solo un tipo de archivo? Parece que solo lo hace para el directorio de destino.
Charlie Parker
1
¡Gracias por esto! Necesita --include '*.ext'y no--include '.ext'
gbyte
13
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:
No coincidir con ningún patrón significa que se copiará un archivo.
El algoritmo se cierra una vez que coincide cualquier patrón
Además, algo que termina con una barra es un directorio coincidente (como lo find -type dharía).
Muchas gracias por explicarme lo que está pasando. Ahora hay muchas más posibilidades de que no olvide el comando.
MohamedEzz
3
"El algoritmo se cierra una vez que coincide cualquier patrón" : esta es la clave, y ninguna de las respuestas con calificaciones más altas lo explica con tanta claridad y anticipación como lo hizo aquí. Por supuesto, esto está en la página de manual en algún momento, y si Lo habría leído todo con atención, lo habría visto. Aún así, gracias.
TheDudeAbides
0
Si alguien busca esto ... Quería rsync solo archivos y carpetas específicos y logré hacerlo con este comando: rsync --include-from=rsync-files
Escribí esta práctica función y puse mis scripts bash o ~/.bash_aliases. Probado la sincronización local en Linux con bash e awkinstalado. 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}
Ventajas:
corto, útil y extensible cuando se quiere agregar más argumentos (es decir --dry-run).
rsync
, esto se puede lograr muy bien con los componentes internos del shell?Respuestas:
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:
Para rsync versión 3.0.6 o superior, el orden debe modificarse de la siguiente manera (ver comentarios):
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
fuente
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
fuente
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:
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!
fuente
include
y lasexclude
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:
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.
.sh
archivoFinalmente,
--prune-empty-directories
evita que la primera regla genere directorios vacíos por todas partes.fuente
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:
fuente
Escribí esta práctica función y puse mis scripts bash o
~/.bash_aliases
. Probado la sincronización local en Linux con bash eawk
instalado. FuncionaVentajas:
corto, útil y extensible cuando se quiere agregar más argumentos (es decir
--dry-run
).Ejemplo:
fuente