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 find
qui 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 find
implé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/dir
comme dir
dans 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 find
pour parcourir la structure source et appeler mkdir
pour chaque répertoire qu'il rencontre.
Cet exemple, à l'aide de find
, copiera la structure de votre répertoire de foo
vers/tmp/another/
( cd foo && find -type d -exec sh -c 'for d do mkdir -p "/tmp/another/$d"; done' sh {} + )
La exec
boucle crée l'ensemble des répertoires en dessous foo
, qui est ensuite transmis au mkdir
. Si vous ne disposez pas d'une version find
qui comprend, +
vous pouvez l'utiliser \;
au détriment de l'efficacité. Remplacez mkdir
par echo mkdir
pour 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' globstar
option:
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 ls
directement 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-tree
qui étaient présents sous old-tree
. mtree
ne 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-tree
horodatages correspondent à ceux de old-tree
, exécutez simplement à mtree
nouveau. Étant donné que les répertoires existent déjà, mtree
modifieront 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
find
charge l'interpolation de{}
dans une autre chaîne.