GNU/Linux >> Tutoriales Linux >  >> Linux

rsync usando expresiones regulares para incluir solo algunos archivos

Sugeriría usar la opción de filtro de rsync. Para su ejemplo, simplemente escriba:

rsync -vam -f'+ *[Nn][Aa][Mm][E]*' -f'+ */' -f'- *' a b

la primera regla de filtro le dice a rsync qué patrones incluir. La segunda regla es necesaria para decirle a rsync que inspeccione todos los directorios en su recorrido. Para evitar que se incluyan directorios vacíos, -m los excluye explícitamente opción. La última regla de filtro le dice a rsync que elimine todos los patrones restantes que todavía no coincidían hasta ahora.


rsync no habla expresiones regulares. Puede utilizar find y grep, aunque se vuelve un poco arcano. Para encontrar los archivos de destino:

find a/ |
grep -i 'name'

Pero todos tienen el prefijo "a/", lo cual tiene sentido, pero queremos terminar con una lista de patrones de inclusión aceptables para rsync, y como el prefijo "a/" no funciona para rsync, Lo eliminaré con un corte:

find . |
grep -i 'name' |
cut -d / -f 2-

Todavía hay un problema:aún perderemos archivos en subdirectorios, porque rsync no busca directorios en la lista de exclusión. Voy a usar awk para agregar los subdirectorios de cualquier archivo coincidente a la lista de patrones de inclusión:

find a/ |
grep -i 'name' |
cut -d / -f 2- |
awk -F/ '{print; while(/\//) {sub("/[^/]*$", ""); print}}'

Todo lo que queda es enviar la lista a rsync; podemos usar el argumento --include-from=- para proporcionar una lista de patrones para rsync en la entrada estándar. Entonces, en total:

find a/ |
grep -i 'name' |
cut -d / -f 2- |
awk -F/ '{print; while(/\//) {sub("/[^/]*$", ""); print}}' |
rsync -avvz --include-from=- --exclude='*' ./a/ ./b/

Tenga en cuenta que se hace referencia al directorio de origen 'a' a través de dos rutas diferentes:"a/" y "./a/". Esto es sutil pero importante. Para hacer las cosas más consistentes, haré un cambio final y siempre me referiré al directorio fuente como "./a/". Sin embargo, esto significa que el comando de corte tiene que cambiar, ya que habrá un "./" adicional al frente de los resultados de find:

find ./a/ |
grep -i 'name' |
cut -d / -f 3- |
awk -F/ '{print; while(/\//) {sub("/[^/]*$", ""); print}}' |
rsync -avvz --include-from=- --exclude='*' ./a/ ./b/

Si usa ZSH, puede usar el indicador (#i) para desactivar la distinción entre mayúsculas y minúsculas. Ejemplo:

$ touch NAME
$ ls (#i)*name*
NAME

ZSH también admite exclusiones, que se especifican como la ruta normal pero tienen un ~

inicial
$ touch aa ab ac
$ ls *~*c
aa ab

Puede encadenar exclusiones:

$ ls *~*c~*b
aa

Finalmente, puede especificar qué tipo de archivo desea devolver (directorio, archivo, etc.). Esto se hace con (/) para directorio y (.) para archivo.

$ touch file
$ mkdir dir
$ ls *(.)
file

Basado en todo esto, haría ese comando como:

rsync -avvz *(/) (#i)*name* ./a/ ./b/

(No veo la necesidad de una exclusión con estos selectores)


Linux
  1. ¿Cómo silenciar selectivamente Rsync?

  2. Haz una copia de seguridad de tus archivos con rsync

  3. 6 ejemplos de rsync para excluir varios archivos y directorios utilizando excluir de

  4. Cómo copiar directorios recursivamente usando rsync mientras se excluyen archivos específicos

  5. Cómo buscar archivos usando expresiones regulares en el script de shell de Linux

Reanudar archivos parcialmente transferidos a través de SSH usando Rsync

Cómo hacer una copia de seguridad de archivos y directorios usando Rsync en Linux

Transferir archivos usando WinSCP

cp -r sin archivos ocultos

¿Cómo puedo enumerar solo archivos no vacíos usando ls?

SCP transfiere solo archivos modificados