Copia la struttura delle cartelle (senza file) da una posizione a un'altra


94

Voglio creare un clone della struttura del nostro file server multi-terabyte. So che cp --parents può spostare un file e la sua struttura principale, ma esiste un modo per copiare intatta la struttura della directory?

Voglio copiare su un sistema Linux e il nostro file server è CIFS montato lì.



La soluzione rsync dal post di commento sopra sembra più ordinata.
YE

Risposte:


158

Potresti fare qualcosa come:

find . -type d > dirs.txt

per creare l'elenco delle directory, quindi

xargs mkdir -p < dirs.txt

per creare le directory sulla destinazione.


8
Questa soluzione non funzionerà se hai spazi nei nomi delle directory.
Jealie

29
@ Jealie Cambia i comandi in find . -type d -print0 >dirs.txte xargs -0 mkdir -p <dirs.txt. Ciò farà sì che entrambi i comandi utilizzino valori nulli come separatori invece di spazi bianchi.
user1207177

3
xargspuò superare la lunghezza massima del comando del sistema quando inizi a gestire ordini di centinaia o migliaia, quindi usalo con cautela. (Trova il limite di lunghezza del comando con getconf ARG_MAX.) Con molte directory, potresti dover scrivere uno script per eseguire il ciclo dell'output.
palswim

1
E per quanto riguarda le autorizzazioni e gli attributi verranno mantenuti?
Ashish Karpe

3
@TrevorBoydSmith: grazie per il tuo commento. La domanda originale non menzionava nulla sulla necessità di preservare autorizzazioni, proprietà o attributi. Ciò richiederebbe una soluzione diversa, come hai detto, ma quanto sopra è sufficiente per rispondere alla domanda così come viene posta.
Greg Hewgill

79
cd /path/to/directories &&
find . -type d -exec mkdir -p -- /path/to/backup/{} \;

3
La migliore risposta da parte mia con trova. Altrimenti puoi provare la rsyncsoluzione dalla risposta di Chen Levy in questa domanda SO
Mat M

3
Cosa fa l'opzione - mkdir?
Bruce_Warrior

9
--è un terminatore di opzioni di utilità GNU standard. Significa "hey mkdir, qualsiasi argomento dopo questo, non è un flag, quindi trattalo come un argomento di file, anche se inizia con un carattere '-'."
amphetamachine

4
questa risposta inoltre non mantiene le autorizzazioni e gli attributi della directory . Usa rynsc per conservare le autorizzazioni e gli attributi
Trevor Boyd Smith

35

Ecco una semplice soluzione usando rsync:

rsync -av -f"+ */" -f"- *" "$source" "$target"
  • una linea
  • nessun problema con gli spazi
  • conserva le autorizzazioni

Ho trovato questa soluzione lì


10
stesso ma più leggibilersync -a --include '*/' --exclude '*' "$source" "$target"
Sylvain

1
Il problema con questa soluzione è: le mie cartelle contengono migliaia di file e rsync impiega anni solo per sincronizzare una dozzina di cartelle.
Christopher K.

6

Non so se stai cercando una soluzione su Linux. Se è così, puoi provare questo:

$ mkdir destdir
$ cd sourcedir
$ find . -type d | cpio -pdvm destdir

cpio non sembra funzionare per me, almeno con i parametri che hai specificato.
r00fus

@ r00fus - leggi il manuale di cpio o fai
zerodin

6

Questo copia le directory e gli attributi dei file, ma non i dati dei file:

cp -R --attributes-only SOURCE DEST

Quindi puoi eliminare gli attributi dei file se non ti interessano:

find DEST -type f -exec rm {} \;

1
Sarebbe eccellente, ma hai dimenticato di menzionare il salvataggio di proprietà, timestamp e autorizzazioni. Quindi ha prodotto un pasticcio in Win7 / cygwin: utente NULL_SID, ordine errato dei permessi, non può modificare i permessi, ecc. E non può accedere alla struttura dei file prodotta.
WebComer

1
Dovrei pensare che la colpa sia di chiunque cerchi di utilizzare Windows per un lavoro reale.
tripleee

cp -R --attributes-only --preserve = all --parents -v SOURCE DEST
Gábor

2

La seguente soluzione ha funzionato bene per me in vari ambienti:

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

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

2

Funziona:

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

Basta sostituire SOURCE_DIR e DEST_DIR.


2

Questo risolve anche il problema con gli spazi bianchi:

Nella directory originale / sorgente:

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

quindi ricrearlo nella directory appena creata:

mkdir -p <../<SOURCEDIR>/dirs2.txt

1

Sostituisci target_dire source_dircon i valori appropriati:

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

Testato su OSX + Ubuntu.


0

Uno script Python di Sergiy Kolodyazhnyy pubblicato su Copia solo cartelle e non file? :

#!/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 dalla shell:

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:


0

Un altro approccio è usare il treeche è abbastanza comodo e navigare negli alberi di directory in base alle sue forti opzioni. Ci sono opzioni solo per directory, escludere directory vuote, escludere nomi con pattern, includere solo nomi con pattern, ecc.man tree

Vantaggio : puoi modificare o rivedere l'elenco, o se fai molti script e crei spesso un batch di directory vuote

Approccio : crea un elenco di directory usando tree, usa quell'elenco come input per argomentimkdir

tree -dfi --noreport > some_dir_file.txt

-dfi elenca solo le directory, stampa il percorso completo per ogni nome, fa in modo che l'albero non stampi le righe di rientro,

--noreport Omette la stampa del file e del report della directory alla fine dell'elenco dell'albero, solo per fare in modo che il file di output non contenga alcun fluff

Quindi vai alla destinazione in cui desideri le directory vuote ed esegui

xargs mkdir < some_dir_file.txt

0
find source/ -type f  | rsync -a --exclude-from - source/ target/

Copia la directory solo con i permessi e la proprietà associati


0

Soluzione a 1 linea:

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

-1

Se puoi ottenere l'accesso da una macchina Windows, puoi usare xcopy con / T e / E per copiare solo la struttura delle cartelle (la / E include cartelle vuote)

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

[MODIFICARE!]

Questo usa rsync per ricreare la struttura della directory ma senza i file. http://psung.blogspot.com/2008/05/copying-directory-trees-with-rsync.html

Potrebbe effettivamente essere migliore :)


1
Sfortunatamente, il nostro file server che serve CIFS non esegue Windows, quindi non è possibile eseguire comandi Win.
r00fus

Grazie, il metodo rsync ha funzionato perfettamente per me. È compatibile anche con gli spazi nei nomi delle directory.
Glutanimato

-1

Ecco una soluzione in php che:

  • copia le directory (non ricorsivamente, solo un livello)
  • conserva le autorizzazioni
  • a differenza della soluzione rsync, è veloce anche con directory contenenti migliaia di file in quanto non entra nemmeno nelle cartelle
  • non ha problemi con gli spazi
  • dovrebbe essere facile da leggere e regolare

Crea un file simile syncDirs.phpa questo contenuto:

<?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());
}

Eseguilo come utente che dispone di diritti sufficienti:

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


Non devi amare PHP e non devi usarlo. Ma l'OP non ha specificato se vuole una soluzione in un linguaggio specifico e, piaccia o no, PHP è installato comunque su molti sistemi Linux poiché l'80% del web utilizza PHP ( w3techs.com/technologies/details/pl- php / all / all ).
Christopher K.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.