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 find
supporto 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 find
con l'espansione di *
. Meglio usare solo .
lì. Inoltre, la maggior parte delle find
implementazioni 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/dir
come dir
nella 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 find
per attraversare la struttura di origine e chiamare mkdir
per ogni directory che incontra.
Questo esempio, usando find
, copia la struttura della directory da foo
a/tmp/another/
( cd foo && find -type d -exec sh -c 'for d do mkdir -p "/tmp/another/$d"; done' sh {} + )
Il exec
ciclo crea il set di directory sottostanti foo
, che viene quindi passato al file mkdir
. Se non si dispone di una versione find
che capisce, +
è possibile utilizzare \;
a costo dell'efficienza. Sostituisci mkdir
con echo mkdir
per 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' globstar
opzione:
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 ls
l'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-tree
che erano presenti sotto old-tree
. mtree
non 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-tree
timestamp corrispondano a quelli in old-tree
, eseguire semplicemente di mtree
nuovo. Poiché le directory esistono già, mtree
modificheranno 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
find
supportano l'interpolazione di{}
in un'altra stringa.