Copie la estructura de carpetas (sin archivos) de una ubicación a otra

94

Quiero crear un clon de la estructura de nuestro servidor de archivos de varios terabytes. Sé que cp --parents puede mover un archivo y su estructura principal, pero ¿hay alguna forma de copiar la estructura del directorio intacta?

Quiero copiar a un sistema linux y nuestro servidor de archivos tiene CIFS montado allí.

r00fus
fuente
1
Posible duplicado de Rsync ¿cómo incluir directorios pero no archivos?
Trevor Boyd Smith
La solución rsync de la publicación de comentarios anterior se ve más ordenada.
YE

Respuestas:

158

Podrías hacer algo como:

find . -type d > dirs.txt

para crear la lista de directorios, luego

xargs mkdir -p < dirs.txt

para crear los directorios en el destino.

Greg Hewgill
fuente
8
Esta solución no funcionará si tiene espacios en los nombres de su directorio.
Jealie
29
@Jealie Cambia los comandos a find . -type d -print0 >dirs.txty xargs -0 mkdir -p <dirs.txt. Esto hará que ambos comandos usen nulos como separadores en lugar de espacios en blanco.
user1207177
3
xargspuede exceder la longitud máxima de comando del sistema cuando comienza a trabajar con pedidos de cientos o miles, así que use esto con precaución. (Encuentre el límite de longitud del comando con getconf ARG_MAX.) Con muchos directorios, es posible que tenga que escribir un script para recorrer la salida.
palswim
1
¿Y qué hay de los permisos y atributos que se conservarán?
Ashish Karpe
3
@TrevorBoydSmith: Gracias por tu comentario. La pregunta original no mencionó nada sobre la necesidad de preservar permisos, propiedad o atributos. Hacerlo requeriría una solución diferente, como menciona, pero lo anterior es suficiente para responder la pregunta tal como se plantea.
Greg Hewgill
79
cd /path/to/directories &&
find . -type d -exec mkdir -p -- /path/to/backup/{} \;
anfetamáquina
fuente
3
La mejor respuesta de mi parte con encontrar. De lo contrario, puede probar la rsyncsolución de la respuesta de Chen Levy en esta pregunta SO
Mat M
3
¿Qué significa la opción de - mkdir?
Bruce_Warrior
9
--es un terminador de opción de utilidad GNU estándar. Significa "hey mkdir, cualquier argumento después de este, no es una bandera, así que trátelo como un argumento de archivo, incluso si comienza con un carácter '-'".
amphetamachine
4
esta respuesta tampoco conserva los permisos y atributos del directorio . Use rynsc para preservar los permisos y atributos
Trevor Boyd Smith
35

Aquí hay una solución simple usando rsync:

rsync -av -f"+ */" -f"- *" "$source" "$target"
  • una línea
  • sin problemas con los espacios
  • preservar los permisos

Encontré esta solución allí

Gildas
fuente
10
Lo mismo pero más legiblersync -a --include '*/' --exclude '*' "$source" "$target"
Sylvain
1
El problema con esta solución es: mis carpetas contienen miles de archivos y rsync tarda mucho en sincronizar una docena de carpetas.
Christopher K.
6

No sé si está buscando una solución en Linux. Si es así, puede intentar esto:

$ mkdir destdir
$ cd sourcedir
$ find . -type d | cpio -pdvm destdir
zerodina
fuente
cpio no parece funcionar para mí, al menos con los parámetros que especificó.
r00fus
@ r00fus - lea el manual de cpio o consulte gnu.org/software/cpio
zerodin
6

Esto copia los atributos de los directorios y archivos, pero no los datos de los archivos:

cp -R --attributes-only SOURCE DEST

Luego, puede eliminar los atributos de los archivos si no está interesado en ellos:

find DEST -type f -exec rm {} \;
toliveira
fuente
1
Sería excelente, pero olvidó mencionar el ahorro de propiedad, marca de tiempo y permisos. Por lo tanto, produjo un desastre en Win7 / cygwin: usuario NULL_SID, orden de permisos incorrecto, no puede editar permisos, etc. y no puede acceder a la estructura de archivos producida.
WebComer
1
Creo que la culpa recae directamente en quien intenta usar Windows para un trabajo real.
tripleee
cp -R --attributes-only --preserve = all --parents -v SOURCE DEST
Gábor
2

La siguiente solución funcionó bien para mí en varios entornos:

sourceDir="some/directory"
targetDir="any/other/directory"

find "$sourceDir" -type d | sed -e "s?$sourceDir?$targetDir?" | xargs mkdir -p
yaccob
fuente
2

Esto funciona:

find ./<SOURCE_DIR>/ -type d | sed 's/\.\/<SOURCE_DIR>//g' | xargs -I {} mkdir -p <DEST_DIR>"/{}"

Simplemente reemplace SOURCE_DIR y DEST_DIR.

mijhael3000
fuente
2

Esto resuelve incluso el problema de los espacios en blanco:

En el directorio original / fuente:

find . -type d -exec echo "'{}'" \; > dirs2.txt

luego vuelva a crearlo en el directorio recién creado:

mkdir -p <../<SOURCEDIR>/dirs2.txt
Thim
fuente
1

Sustituir target_diry source_dircon los valores adecuados:

cd target_dir && (cd source_dir; find . -type d ! -name .) | xargs -i mkdir -p "{}"

Probado en OSX + Ubuntu.

luissquall
fuente
0

¿Un script de Python de Sergiy Kolodyazhnyy publicado en Copiar solo carpetas, no archivos? :

#!/usr/bin/env python
import os,sys
dirs=[ r for r,s,f in os.walk(".") if r != "."]
for i in dirs:
    os.makedirs(os.path.join(sys.argv[1],i)) 

o de la cáscara:

python -c 'import os,sys;dirs=[ r for r,s,f in os.walk(".") if r != "."];[os.makedirs(os.path.join(sys.argv[1],i)) for i in dirs]' ~/new_destination

FYI:

Franck Dernoncourt
fuente
0

Otro enfoque es usar el treeque es bastante útil y navegar por árboles de directorios en función de sus opciones sólidas. Hay opciones para solo directorio, excluir directorios vacíos, excluir nombres con patrón, incluir solo nombres con patrón, etc.man tree

Ventaja : puede editar o revisar la lista, o si realiza muchas secuencias de comandos y crea un lote de directorios vacíos con frecuencia

Enfoque : cree una lista de directorios usando tree, use esa lista como entrada de argumentos paramkdir

tree -dfi --noreport > some_dir_file.txt

-dfi enumera solo directorios, imprime la ruta completa para cada nombre, hace que el árbol no imprima las líneas de sangría,

--noreport Omite la impresión del informe de archivos y directorios al final de la lista del árbol, solo para que el archivo de salida no contenga ninguna pelusa.

Luego vaya al destino donde desea los directorios vacíos y ejecute

xargs mkdir < some_dir_file.txt
hermano-bilo
fuente
0
find source/ -type f  | rsync -a --exclude-from - source/ target/

Copiar directorio solo con permiso y propiedad asociados

Tigre peng
fuente
0

Solución de 1 línea:

find . -type d -exec mkdir -p /path/to/copy/directory/tree/{} \;
Igor
fuente
-1

Si puede obtener acceso desde una máquina con Windows, puede usar xcopy con / T y / E para copiar solo la estructura de carpetas (la / E incluye carpetas vacías)

http://ss64.com/nt/xcopy.html

[¡EDITAR!]

Este usa rsync para recrear la estructura del directorio pero sin los archivos. http://psung.blogspot.com/2008/05/copying-directory-trees-with-rsync.html

En realidad, podría ser mejor :)

dotalquimia
fuente
1
Desafortunadamente, nuestro servidor de archivos CIFS no está ejecutando Windows, por lo que no puede hacerlo con los comandos win.
r00fus
Gracias, el método rsync funcionó perfectamente bien para mí. También es compatible con espacios en los nombres de directorios.
Glutanimate
-1

Aquí hay una solución en php que:

  • copia los directorios (no de forma recursiva, solo un nivel)
  • conserva los permisos
  • a diferencia de la solución rsync, es rápida incluso con directorios que contienen miles de archivos, ya que ni siquiera entra en las carpetas
  • no tiene problemas con los espacios
  • debe ser fácil de leer y ajustar

Crea un archivo como syncDirs.phpcon este contenido:

<?php
foreach (new DirectoryIterator($argv[1]) as $f) {
    if($f->isDot() || !$f->isDir()) continue;
        mkdir($argv[2].'/'.$f->getFilename(), $f->getPerms());
        chown($argv[2].'/'.$f->getFilename(), $f->getOwner());
        chgrp($argv[2].'/'.$f->getFilename(), $f->getGroup());
}

Ejecútelo como usuario que tiene suficientes derechos:

sudo php syncDirs.php /var/source /var/destination

Christopher K.
fuente
No tiene que gustarle PHP y no tiene que usarlo. Pero el OP no especificó si quiere una solución en un lenguaje específico y, le guste o no, PHP está instalado de todos modos en muchos sistemas Linux ya que el 80% de la web usa PHP ( w3techs.com/technologies/details/pl- php / all / all ).
Christopher K.