¿Cómo puedo sincronizar un conjunto de subdirectorios?

¿Cómo puedo sincronizar un conjunto de subdirectorios?

Tengo un directorio fuente que se parece al siguiente (con numerosos subdirectorios dentro de los directorios src y bin):

  • directorio_superior
    • proyecto1
      • src/
      • papelera/
      • guiones/
      • algún archivo.txt
    • proyecto2
      • src/
      • papelera/
      • objetivo
        • papelera/
      • archivo.xml

Me gustaría sincronizar solo los directorios bin directamente debajo de los directorios del proyecto (es decir, ignorar top_dir/proj2/target/bin/) y su contenido en el directorio de destino, para que se vea así:

  • directorio_superior
    • proyecto1
      • papelera
    • proyecto2
      • papelera

Probablemente podría hacerlo funcionar enumerando explícitamente cada directorio bin (hay alrededor de 15 en mi escenario real) en un archivo de inclusión, pero estaba pensando que debe haber una manera de decir que quiero sincronizar todos los top_dir/ */directorios bin.

Respuesta1

Posibilidad 1

Usando la expansión 1 del shell en lugar de rsynclas reglas de filtro de , puede hacer lo siguiente:

a. Para incluir todos binlos directorios en la top_dirjerarquía:

rsync -av -R top_dir/**/bin/ destination_path

Aquí -Rhay un parámetro rsync 2 que representarelativo. man rsynclo explica como

Utilice rutas relativas. Esto significa que los nombres de ruta completos especificados en la línea de comando se envían al servidor en lugar de solo las últimas partes de los nombres de archivo. Esto es particularmente útil cuando desea enviar varios directorios diferentes al mismo tiempo.

pero en esencia significa que se conserva la estructura del directorio.

**es un patrón global de shell y busca recursivamente directorios nombrados binbajo top_dir. Entonces, con el ejemplo anterior, la línea de comando se expande a:

rsync -av -R top_dir/proj1/bin/ top_dir/proj2/bin/ destination_path

b. Si solo desea incluir bindirectorios un nivel por debajo del directorio del proyecto, simplemente use uno único *(¡que también funciona con shells "antiguos"!):

rsync -av -R top_dir/*/bin/ destination_path

1 Necesitas una recienteintentoversión (>4) y activar el globbing recursivo mediante shopts -s globstar. ConzshEl globbing recursivo es el predeterminado.

2 rsync versión v3.2.3 protocolo versión 31 en Linux.

Posibilidad 2

Solo usando las reglas de filtrado de rsync necesitas:

a. Para incluir todos binlos directorios en la top_dirjerarquía:

rsync -av -m --include='**/' --include='**/bin/**' --exclude='*' top_dir/ destination_path

Es posible que la primera includeregla no sea obvia 3,/ pero garantiza que se busquen en todos los directorios (tenga en cuenta el final ), la segunda agrega todo lo que hay en binlos directorios y la excluderegla excluye todo lo demás. -mse asegura de que los directorios vacíos no se copien.

b. Para incluir solo un nivel debajo del directorio del proyecto:

rsync -av -m  --include='/*/' --include='/*/bin/***' --exclude='*' top_dir/ destination_path

Usando ***la sintaxis de rsync >= 2.6.7. El líder /en los patrones representa top_dir, de lo contrario, los patrones se comparan con elfinde la ruta del archivo.


3 Buscar /some/path/this-file-will-not-be-foundenman rsync

Respuesta2

Puede excluir todos srclos directorios usando--exclude src/

información relacionada