Respuestas:
Prueba esto,
cd /source/dir/path
find . -type d -exec mkdir -p -- /destination/directory/{} \;
. -type d
Para enumerar directorios en la ruta actual de forma recursiva.mkdir -p -- /destination/directory/{}
crear directorio en el destino. Esto se basa en una find
que admite la expansión {}
en el medio de una palabra de argumento.
/source/dir/path
, entonces este puede fallar con una "lista de argumentos demasiado tiempo" cuando los intentos de concha para llamar find
a la expansión de *
. Es mejor usarlo .
allí. Además, la mayoría de las find
implementaciones permiten {}
su uso incluso cuando se concatenan con otra cadena, pero no es universal.
.
lugar de *
en este caso. (El uso de xarg para el rendimiento y la seguridad probablemente requeriría un script externo para la concatenación de ruta)
Utilizando rsync
:
rsync -a --include='*/' --exclude='*' /some/path/dir/ dir
Esto recrearía la estructura de directorios /some/path/dir
como dir
en el directorio actual, sin copiar ningún archivo.
Cualquier directorio encontrado en la ruta de origen se crearía en el destino debido al patrón de inclusión, pero se excluiría cualquier otra cosa. Como efecto secundario del uso de -a
( --archive
), obtendrá las mismas marcas de tiempo en todos los subdirectorios en el destino que en la fuente. Esto también funciona para crear estructuras de directorios locales a partir de directorios remotos (y viceversa).
rsync
!
Puede usar find
para recorrer la estructura de origen y llamar mkdir
a cada directorio que encuentre.
Este ejemplo, usando find
, copiará la estructura de su directorio de foo
a/tmp/another/
( cd foo && find -type d -exec sh -c 'for d do mkdir -p "/tmp/another/$d"; done' sh {} + )
El exec
bucle crea el conjunto de directorios debajo foo
, que luego se pasa al mkdir
. Si no tiene una versión find
que comprenda +
, puede usarla \;
a costa de la eficiencia. Sustitúyalo mkdir
por echo mkdir
para ver qué sucedería sin hacerlo realmente.
... -exec sh -c 'for dirpath do mkdir -p "/some/path/$dirpath"; done' sh {} +
find: In ‘-exec ... {} +’ the ‘{}’ must appear by itself, but you specified ‘/tmp/another/{}’
(aunque sí funciona -exec ... \;
)
/path/to/{}
pero ahora no puedo encontrar ninguna versión donde funcione, así que he adaptado la solución. Gracias
Con el shell bash, puede solicitarle la expansión de cada directorio con la globstar
opción:
shopt -s globstar
y luego copie los directorios con un bucle:
for dir in **/
do
mkdir -p /path/to/dest/"$dir"
done
... o si pensabas que todos encajarían dentro de una llamada para mkdir
:
set -- **/
mkdir -- "${@/#//path/to/dest/}"
Esa es la sintaxis de la matriz bash que dice: "tome todos los elementos de la $@
matriz y reemplace el comienzo de cada uno de ellos /path/to/dest/
.
No conozco una forma de obtener ls
resultados directamente como una lista de expansión de llaves. Si trató de masajear la salida de la **/
expansión en una expansión de llave, necesitaría tener cuidado de:
{
o ${
secuenciaNo lo recomendaría
La pregunta es un duplicado entre sitios de /superuser/1389580/copy-directory-structure-only-at-year-end
Este tipo de tarea es un caso de uso clásico para mtree
:
$ mkdir new-tree
$ mtree -cp old-tree | mtree -tdUp new-tree
.: modification time (Tue Sep 24 14:27:07 2019, Tue Sep 24 16:34:57 2019, modified)
./bar missing (created)
./bar/bar2 missing (created)
./bar/bar2/bar3 missing (created)
./bar/bar2/bar3/bar4 missing (created)
./foo missing (created)
./foo/foo2 missing (created)
./foo/foo2/foo3 missing (created)
Lo anterior crea todos los directorios new-tree
que estaban presentes en old-tree
. mtree
Sin embargo, no establece marcas de tiempo en los directorios recién creados, por lo que el árbol resultante se ve así:
$ find old-tree new-tree -ls
20147 1 drwx--x--- 4 jim jim 5 Sep 24 14:27 old-tree
20048 1 drwx--x--- 3 jim jim 4 Sep 24 14:27 old-tree/foo
20363 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/foo/file
20073 1 drwx--x--- 3 jim jim 4 Sep 24 14:27 old-tree/foo/foo2
20074 1 drwx--x--- 2 jim jim 3 Sep 24 14:27 old-tree/foo/foo2/foo3
20365 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/foo/foo2/foo3/file
20364 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/foo/foo2/file
20051 1 drwx--x--- 3 jim jim 4 Sep 24 14:27 old-tree/bar
20077 1 drwx--x--- 3 jim jim 4 Sep 24 14:27 old-tree/bar/bar2
20368 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/bar/bar2/file
20078 1 drwx--x--- 3 jim jim 4 Sep 24 14:27 old-tree/bar/bar2/bar3
20369 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/bar/bar2/bar3/file
20079 1 drwx--x--- 2 jim jim 3 Sep 24 14:27 old-tree/bar/bar2/bar3/bar4
20370 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/bar/bar2/bar3/bar4/file
20366 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/bar/file
20362 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/file
134489 1 drwx--x--- 4 jim jim 4 Sep 24 16:34 new-tree
134490 1 drwx--x--- 3 jim jim 3 Sep 24 16:34 new-tree/bar
134491 1 drwx--x--- 3 jim jim 3 Sep 24 16:34 new-tree/bar/bar2
134492 1 drwx--x--- 3 jim jim 3 Sep 24 16:34 new-tree/bar/bar2/bar3
134493 1 drwx--x--- 2 jim jim 2 Sep 24 16:34 new-tree/bar/bar2/bar3/bar4
134494 1 drwx--x--- 3 jim jim 3 Sep 24 16:34 new-tree/foo
134495 1 drwx--x--- 3 jim jim 3 Sep 24 16:34 new-tree/foo/foo2
134496 1 drwx--x--- 2 jim jim 2 Sep 24 16:34 new-tree/foo/foo2/foo3
Si prefiere que las new-tree
marcas de tiempo coincidan old-tree
, simplemente mtree
vuelva a ejecutar . Como los directorios ya existen, mtree
modificará las marcas de tiempo para que coincidan con la especificación de origen:
$ mtree -cp old-tree | mtree -tdUp new-tree
.: modification time (Tue Sep 24 14:27:07 2019, Tue Sep 24 16:34:57 2019, modified)
bar: modification time (Tue Sep 24 14:27:07 2019, Tue Sep 24 16:34:57 2019, modified)
bar/bar2:
modification time (Tue Sep 24 14:27:07 2019, Tue Sep 24 16:34:57 2019, modified)
bar/bar2/bar3:
modification time (Tue Sep 24 14:27:07 2019, Tue Sep 24 16:34:57 2019, modified)
bar/bar2/bar3/bar4:
modification time (Tue Sep 24 14:27:07 2019, Tue Sep 24 16:34:57 2019, modified)
foo: modification time (Tue Sep 24 14:27:07 2019, Tue Sep 24 16:34:57 2019, modified)
foo/foo2:
modification time (Tue Sep 24 14:27:07 2019, Tue Sep 24 16:34:57 2019, modified)
foo/foo2/foo3:
modification time (Tue Sep 24 14:27:07 2019, Tue Sep 24 16:34:57 2019, modified)
$ find old-tree new-tree -ls
20147 1 drwx--x--- 4 jim jim 5 Sep 24 14:27 old-tree
20048 1 drwx--x--- 3 jim jim 4 Sep 24 14:27 old-tree/foo
20363 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/foo/file
20073 1 drwx--x--- 3 jim jim 4 Sep 24 14:27 old-tree/foo/foo2
20074 1 drwx--x--- 2 jim jim 3 Sep 24 14:27 old-tree/foo/foo2/foo3
20365 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/foo/foo2/foo3/file
20364 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/foo/foo2/file
20051 1 drwx--x--- 3 jim jim 4 Sep 24 14:27 old-tree/bar
20077 1 drwx--x--- 3 jim jim 4 Sep 24 14:27 old-tree/bar/bar2
20368 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/bar/bar2/file
20078 1 drwx--x--- 3 jim jim 4 Sep 24 14:27 old-tree/bar/bar2/bar3
20369 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/bar/bar2/bar3/file
20079 1 drwx--x--- 2 jim jim 3 Sep 24 14:27 old-tree/bar/bar2/bar3/bar4
20370 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/bar/bar2/bar3/bar4/file
20366 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/bar/file
20362 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/file
134489 1 drwx--x--- 4 jim jim 4 Sep 24 14:27 new-tree
134490 1 drwx--x--- 3 jim jim 3 Sep 24 14:27 new-tree/bar
134491 1 drwx--x--- 3 jim jim 3 Sep 24 14:27 new-tree/bar/bar2
134492 1 drwx--x--- 3 jim jim 3 Sep 24 14:27 new-tree/bar/bar2/bar3
134493 1 drwx--x--- 2 jim jim 2 Sep 24 14:27 new-tree/bar/bar2/bar3/bar4
134494 1 drwx--x--- 3 jim jim 3 Sep 24 14:27 new-tree/foo
134495 1 drwx--x--- 3 jim jim 3 Sep 24 14:27 new-tree/foo/foo2
134496 1 drwx--x--- 2 jim jim 2 Sep 24 14:27 new-tree/foo/foo2/foo3
find
admiten la interpolación{}
en otra cadena.