Copie un tipo de archivo específico manteniendo la estructura de carpetas
On febrero 10, 2021 by adminTengo una estructura de carpetas con un montón de archivos * .csv esparcidos por las carpetas. Ahora quiero copiar todos los archivos * .csv a otro destino manteniendo la estructura de la carpeta.
Funciona haciendo:
cp --parents *.csv /target cp --parents */*.csv" /target cp --parents */*/*.csv /target cp --parents */*/*/*.csv /target ...
y así sucesivamente, pero me gustaría hacerlo usando un comando.
Responder
find
tiene una -exec
opción muy útil:
find . -name "*.csv" -exec cp --parents \{\} /target \;
Comentarios
- Probablemente debido a esto \ {\} \;
-
'{}'
funciona igual de bien - Aunque
-execdir
es más seguro que-exec
, el simple hecho de reemplazar uno por el otro no conserva la estructura de carpetas como se esperaba. - Por qué get message ‘ Omitiendo directorio ‘ cuando intento copiarlos con su comando?
- ¿Puede explicar por qué el ¿Las llaves deben escaparse aquí?
Respuesta
También puede usar rsync
para esto.
$ rsync -a --prune-empty-dirs --include "*/" --include "*.csv" --exclude "*" source/ target/
Si desea mantener los directorios vacíos del árbol de origen, omita la opción --prune-empty-dirs
:
$ rsync -a --include "*/" --include "*.csv" --exclude "*" source/ target/
Si no desea que se conserven enlaces simbólicos, fechas de modificación, permisos de archivos, propietarios, etc., reemplace -a
con otra combinación de -rlptgoD
. 😉
Comentarios
Responder
Puede usar find y cpio en modo de paso a través
find . -name "*.csv" | cpio -pdm /target
Esto encontrará todos los archivos .csv en el directorio actual y debajo y cópielos en / target manteniendo la estructura del directorio enraizada en .
.
Si usa
find /path/to/files -name "*.csv" | cpio -pdm /target
encontrará todo el archivo en /path/to/files
y más abajo y los copiará en /target/path/to/files
y más abajo .
Comentarios
- Probé todas las respuestas de arriba hacia abajo hasta esta, y esta fue la única que funcionó en el primer intento
- Esta debería ser la respuesta aceptada.
- Encontré los GNU docs útiles: » En modo copy-pass, [solicitado por la opción
-p
, cpio] lee la lista de archivos para copiar desde la entrada estándar; el directorio en el que los copiará se proporciona como un argumento sin opción. » … » -d Crea directorios iniciales donde sea necesario. » … » -m Conserva los tiempos de modificación de archivos anteriores al crear archivos. »
Responder
El comando cp
permite múltiples argumentos fuente:
cp **/*.csv --parents ../target
AVISO: Estoy usando un globo recursivo aquí; esta es la opción globstar
en Bash 4+ y ksh
, y se admite de forma predeterminada en zsh
. Globs recursivos no coinciden con archivos y carpetas ocultos, y algunas implementaciones siguen enlaces simbólicos mientras que otras no .
Si su shell no lo hace » t supl o globs recursivos, o si prefiere no usarlos, puede hacer lo siguiente:
-
*.csv */*.csv */*/*.csv */*/*/*.csv
– esto es por supuesto muy redundante y requiere saber qué tan profunda es la estructura de su directorio. -
$(find . -name "*.csv")
– Este será coincide con archivos y carpetas ocultos.find
también admite especificar si se siguen o no enlaces simbólicos, lo cual puede ser útil.
Comentarios
- ¿Esto es exactamente lo que probé (el glob recursivo) y encontré algunos pero no todos? bastante raro. Obtuve exactamente el mismo resultado al usar el script npm copyfiles, pero si uso el comando find, encuentra todo …
- @Randyaa I ‘ necesitaré algunos más detalles sobre qué archivos, exactamente, ‘ t no se encontraron para ayudarlo. Puede encontrar útil la discusión aquí y aquí sobre el comportamiento preciso del globo recursivo .
- resulta que el globo recursivo no estaba ‘ t habilitado por alguna razón …’ nunca me he encontrado con esto antes, pero lo corrigí con solo una ejecución de
shopt -s globstar
inmediatamente antes de mi comando y todo está bien. ¡Gracias por el seguimiento! -
--parents
era lo que estaba buscando. gracias
Responder
Este me funcionó:
find -name "*.csv" | xargs cp --parents -t /target
Comentarios
- La mejor respuesta con la sintaxis más simple. Funciona bien y es fácil de recordar. En muchos casos,
find [things] | xargs [do stuff]
es muy poderoso. - De acuerdo. Muy sencillo en comparación con algunas de las otras respuestas.
- Se rompe si tiene espacios en los nombres de archivo
- @MichelePiccolini Los espacios en los nombres de archivo se pueden manejar con
find -print0
yxargs -0
.
Responder
De rsync
«s página de manual:
-R, –relative
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. Por ejemplo, si utilizó este comando:
rsync -av /foo/bar/baz.c remote:/tmp/
… esto crearía un archivo llamado baz.c en / tmp / en la máquina remota. Si en su lugar usó
rsync -avR /foo/bar/baz.c remote:/tmp/
entonces se crearía un archivo llamado /tmp/foo/bar/baz.c en la máquina remota, conservando su ruta completa. Estos elementos de ruta adicionales se denominan » impli ed directorios «(es decir los directorios «foo» y «foo / bar» en el ejemplo anterior).
Entonces, esto también funcionaría:
rsync -armR --include="*/" --include="*.csv" --exclude="*" /full/path/to/source/file(s) destination/
Comentarios
- Gracias por proporcionar esta respuesta. Compatible con BSD userland (macOS), y rutas con espacios en ellas.
Respuesta
Suponiendo que desea replicar esta estructura de ./source
a ./destination
:
cd source find . -name "*.csv" | xargs tar cvf - | (cd ../destination ; tar xfp -)
Estoy preparado para contar eso como una línea, el cd source
es un shell incorporado.
Comentarios
-
tar
tiene la opción-C
para evitar tener que cambiar el directorio primero.
-m
es un atajo para--prune-emty-dirs
.-R
se puede agregar para copiar la estructura del directorio principal de la fuente. (vea mi respuesta aquí.)