CLI AI

Copiar archivos por patrón manteniendo la estructura

2026-07-06

Respuesta corta: cp --parents y rsync copian los mismos archivos pero construyen árboles de destino distintos. find src -name '*.txt' -exec cp --parents {} dst/ \; los deja en dst/src/a/b/file; la versión con rsync e include/exclude deja los mismos archivos en dst/a/b/file — sin el segmento src. Elige el método equivocado y obtienes un nivel extra de anidación que nadie te advirtió.

1. ¿Cómo copio archivos que coinciden con un patrón manteniendo la estructura de carpetas?

clai
$ clai copia todos los txt de src a dst, manteniendo la estructura de carpetas→ find src -name '*.txt' -exec cp --parents {} dst/ \;

--parents reconstruye la ruta completa hasta el archivo dentro del destino. El resultado es dst/src/a/b/file: el propio src termina dentro del destino, porque forma parte de la ruta que le diste a find. Esa es la sorpresa de la que trata este artículo.

2. ¿Por qué rsync construye un árbol de destino distinto para la misma tarea?

clai
$ clai copia solo los archivos txt de src a dst2, manteniendo el anidamiento→ rsync -a --include='*/' --include='*.txt' --exclude='*' src/ dst2/

Mismos archivos, resultado distinto: dst2/a/b/file, sin el nivel src. La barra final en src/ significa "el contenido del directorio", no el directorio en sí. El orden de las reglas también importa: primero permite recorrer todos los directorios con --include='*/', luego los archivos que quieres, y solo después excluye el resto. Mueve --exclude='*' al principio y no se copia nada.

3. ¿Cómo compruebo qué copiará rsync antes de ejecutarlo?

clai
$ clai muéstrame qué se copiaría, pero no copies nada→ rsync -avn --include='*/' --include='*.txt' --exclude='*' src/ dst2/

-n es un ensayo en seco. Con reglas de include y exclude que no son triviales, saltárselo significa descubrir el resultado después del hecho en vez de antes. Ejecuta -n primero, siempre.

4. ¿Cómo copio archivos a un servidor remoto con la misma estructura?

clai
$ clai lleva todos los txt con la estructura preservada a un servidor remoto→ find src -name '*.txt' -print0 | tar --null -cf - -T - | ssh user@host 'tar -xf - -C /dest'

tar empaqueta los archivos en un flujo y los desempaqueta al otro lado, con la estructura intacta tal cual. -print0 y --null protegen contra espacios en los nombres. Un solo paso por la red vence a mil copias individuales.

5. ¿Cómo copio sin sobrescribir los archivos más nuevos del destino?

clai
$ clai copia los archivos pero no toques los del destino que sean más nuevos→ rsync -au src/ dst/

-u omite cualquier archivo cuya copia en el destino tenga una fecha de modificación más reciente. Necesario cuando la sincronización va en ambas direcciones, o cuando el destino ya tiene cambios que no quieres perder.

6. ¿Cómo recreo solo el árbol de directorios, sin los archivos?

clai
$ clai crea en dst el mismo árbol de carpetas que hay en src, sin los archivos→ rsync -a --include='*/' --exclude='*' src/ dst/

Las mismas reglas, menos la línea que deja pasar los archivos. Útil para preparar un árbol que recibirá una salida — antes de una conversión de imágenes por lotes, por ejemplo.

Trampas

  • La barra final en el origen lo cambia todo para rsync. src/ copia el contenido; src copia el propio directorio dentro del destino. Uno de los errores más comunes, y es silencioso.
  • El orden de include y exclude es el orden de las reglas. rsync aplica la primera que coincide. --exclude='*' siempre va al final, o se traga todo lo demás antes de que tus include tengan oportunidad.
  • cp --parents es exclusivo de GNU. No existe en macOS — usa ahí la versión con rsync o tar.

Preguntas relacionadas

¿Cómo copio varias extensiones a la vez? Repite --include: --include='*.jpg' --include='*.png' antes de --exclude='*'.

¿Por qué rsync no copió nada? Casi siempre falta --include='*/': sin él, rsync nunca entra en los subdirectorios, así que jamás llega a los archivos.

¿cp o rsync? rsync cuando las reglas superan una sola extensión, cuando quieres un ensayo en seco, o cuando la copia puede interrumpirse. cp para un trabajo rápido, simple y puntual.

Ver también

Describe la copia, lee el comando que escribe CliAI y ejecútalo. Instálalo en una línea.