Risposte:
Prova questo,
cd /source/dir/path
find . -type d -exec mkdir -p -- /destination/directory/{} \;
. -type d Elencare ricorsivamente le directory nel percorso corrente.mkdir -p -- /destination/directory/{} crea directory a destinazione. Questo si basa su un findsupporto che si espande {}nel mezzo di una parola argomento.
/source/dir/path, allora questo potrebbe fallire con un errore "lista argomenti troppo lunga" quando la shell tenta di chiamare findcon l'espansione di *. Meglio usare solo .lì. Inoltre, la maggior parte delle findimplementazioni consente {}di essere utilizzata anche se concatenata con un'altra stringa, ma non è universale.
.Invece di *in questo caso. (L'uso di xarg per prestazioni e sicurezza richiederebbe probabilmente uno script esterno per la concatenazione del percorso)
Utilizzando rsync:
rsync -a --include='*/' --exclude='*' /some/path/dir/ dir
Ciò ricrea la struttura della directory /some/path/dircome dirnella directory corrente, senza copiare alcun file.
Qualsiasi directory trovata nel percorso di origine verrebbe creata sulla destinazione a causa del modello di inclusione, ma qualsiasi altra cosa sarebbe esclusa. Come effetto collaterale dell'uso di -a( --archive), otterrai gli stessi timestamp su tutte le sottodirectory nel target come nella sorgente. Questo funziona anche per la creazione di strutture di directory locali da directory remote (e viceversa).
rsync!
È possibile utilizzare findper attraversare la struttura di origine e chiamare mkdirper ogni directory che incontra.
Questo esempio, usando find, copia la struttura della directory da fooa/tmp/another/
( cd foo && find -type d -exec sh -c 'for d do mkdir -p "/tmp/another/$d"; done' sh {} + )
Il execciclo crea il set di directory sottostanti foo, che viene quindi passato al file mkdir. Se non si dispone di una versione findche capisce, +è possibile utilizzare \;a costo dell'efficienza. Sostituisci mkdircon echo mkdirper vedere cosa sarebbe successo senza farlo davvero.
... -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/{}’(funziona con -exec ... \;, comunque)
/path/to/{}ma ora non riesco a trovare alcuna versione in cui funzioni, quindi ho adattato la soluzione. Grazie
Con la shell bash, potresti chiedere l'espansione di ogni directory con l' globstaropzione:
shopt -s globstar
e quindi copia le directory con un ciclo:
for dir in **/
do
mkdir -p /path/to/dest/"$dir"
done
... o se pensavi che sarebbero rientrati tutti in una chiamata a mkdir:
set -- **/
mkdir -- "${@/#//path/to/dest/}"
Questa è la sintassi dell'array bash che dice: "prendi ogni elemento $@dell'array e sostituisci l'inizio di ciascuno di essi con /path/to/dest/.
Non sono a conoscenza di un modo per ottenere lsl'output direttamente come elenco di espansione del controvento. Se hai provato a massaggiare l'uscita **/dell'espansione in un'espansione di controvento, dovrai fare attenzione a:
{o ${sequenzaNon lo consiglierei.
La domanda è un duplicato su più siti di /superuser/1389580/copy-directory-structure-only-at-year-end
Questo tipo di attività è un classico caso d'uso per 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)
Quanto sopra crea tutte le directory sotto new-treeche erano presenti sotto old-tree. mtreenon imposta i timestamp nelle directory appena create, quindi l'albero risultante è simile al seguente:
$ 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
Se si preferisce che i new-treetimestamp corrispondano a quelli in old-tree, eseguire semplicemente di mtreenuovo. Poiché le directory esistono già, mtreemodificheranno i timestamp in modo che corrispondano alle specifiche di origine:
$ 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
findsupportano l'interpolazione di{}in un'altra stringa.