Réponses:
Essaye ça,
cd /source/dir/path
find . -type d -exec mkdir -p -- /destination/directory/{} \;
. -type d Pour répertorier récursivement les répertoires du chemin actuel.mkdir -p -- /destination/directory/{} créer un répertoire à destination. Cela repose sur un findqui prend en charge l'expansion {}au milieu d'un mot argument.
/source/dir/path, cela peut échouer avec une erreur « liste d'arguments trop long » lorsque les essais de shell pour appeler findà l'expansion de *. Mieux vaut simplement l'utiliser .là-bas. De plus, la plupart des findimplémentations permettent {}d'être utilisées même lorsqu'elles sont concaténées avec une autre chaîne, mais ce n'est pas universel.
.Au lieu de *dans ce cas. (L'utilisation de xarg pour les performances et la sécurité nécessiterait probablement un script externe pour la concaténation du chemin)
En utilisant rsync:
rsync -a --include='*/' --exclude='*' /some/path/dir/ dir
Cela recréerait la structure de répertoires de /some/path/dircomme dirdans le répertoire courant, sans copier aucun fichier.
Tout répertoire rencontré dans le chemin source serait créé sur la cible en raison du modèle d'inclusion, mais tout le reste serait exclu. En tant qu'effet secondaire de l'utilisation de -a( --archive), vous obtiendrez les mêmes horodatages sur tous les sous-répertoires de la cible et de la source. Cela fonctionne également pour créer des structures de répertoires locaux à partir de répertoires distants (et vice versa).
rsync!
Vous pouvez utiliser findpour parcourir la structure source et appeler mkdirpour chaque répertoire qu'il rencontre.
Cet exemple, à l'aide de find, copiera la structure de votre répertoire de foovers/tmp/another/
( cd foo && find -type d -exec sh -c 'for d do mkdir -p "/tmp/another/$d"; done' sh {} + )
La execboucle crée l'ensemble des répertoires en dessous foo, qui est ensuite transmis au mkdir. Si vous ne disposez pas d'une version findqui comprend, +vous pouvez l'utiliser \;au détriment de l'efficacité. Remplacez mkdirpar echo mkdirpour voir ce qui se passerait sans le faire.
... -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/{}’(il fonctionne avec -exec ... \;, cependant)
/path/to/{}mais je ne trouve plus de version où cela fonctionne, j'ai donc adapté la solution. Merci
Avec le shell bash, vous pouvez lui demander l'expansion de chaque répertoire avec l' globstaroption:
shopt -s globstar
puis copiez les répertoires avec une boucle:
for dir in **/
do
mkdir -p /path/to/dest/"$dir"
done
... ou si vous pensiez qu'ils pourraient tous s'intégrer dans un seul appel à mkdir:
set -- **/
mkdir -- "${@/#//path/to/dest/}"
C'est la syntaxe du tableau bash qui dit: "prenez chaque élément du $@tableau et remplacez le début de chacun d'eux par /path/to/dest/.
Je ne suis pas au courant d'un moyen d'obtenir lsdirectement une sortie en tant que liste d'extension d'accolade. Si vous avez essayé de masser la sortie de l' **/expansion en une extension d'accolade, vous devez faire attention à:
{ou ${séquenceJe ne le recommanderais pas.
La question est une copie intersite de /superuser/1389580/copy-directory-structure-only-at-year-end
Ce type de tâche est un cas d'utilisation classique pour 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)
Ce qui précède crée tous les répertoires sous new-treequi étaient présents sous old-tree. mtreene définit pas d'horodatage sur les répertoires nouvellement créés, donc l'arborescence résultante ressemble à ceci:
$ 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 vous préférez que les new-treehorodatages correspondent à ceux de old-tree, exécutez simplement à mtreenouveau. Étant donné que les répertoires existent déjà, mtreemodifieront les horodatages pour correspondre à la spécification source:
$ 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
findcharge l'interpolation de{}dans une autre chaîne.