Ответы:
Попробуй это,
cd /source/dir/path
find . -type d -exec mkdir -p -- /destination/directory/{} \;
. -type d
Список каталогов по текущему пути рекурсивно.mkdir -p -- /destination/directory/{}
создать каталог в месте назначения. Это полагается на то, find
что поддерживает расширение {}
в середине аргументного слова.
/source/dir/path
, то это , возможно , не с «списком аргументов слишком длинной» ошибка , когда оболочка пытается вызвать find
с расширением *
. Лучше просто использовать .
там. Кроме того, большинство find
реализаций позволяет {}
использовать его даже при объединении с другой строкой, но это не универсально.
.
вместо *
в этом случае. (Использование xarg для производительности и безопасности, вероятно, потребует внешнего сценария для конкатенации путей)
Использование rsync
:
rsync -a --include='*/' --exclude='*' /some/path/dir/ dir
Это воссоздает структуру каталогов, /some/path/dir
как dir
в текущем каталоге, без копирования каких-либо файлов.
Любой каталог, найденный в исходном пути, будет создан на цели из-за шаблона включения, но все остальное будет исключено. В качестве побочного эффекта использования -a
( --archive
) вы получите те же временные метки во всех подкаталогах в цели, что и в источнике. Это также работает для создания локальных структур каталогов из удаленных каталогов (и наоборот).
rsync
!
Вы можете использовать find
для обхода структуры источника и вызоваmkdir
для каждого каталога, который встречается.
В этом примере, используя find
, будет копировать структуру каталогов от foo
до/tmp/another/
( cd foo && find -type d -exec sh -c 'for d do mkdir -p "/tmp/another/$d"; done' sh {} + )
exec
Цикл создает множество каталогов под ним foo
, который затем передается mkdir
. Если у вас нет версии, find
которая понимает, +
вы можете использовать \;
за счет эффективности. Подставим mkdir
с , echo mkdir
чтобы увидеть , что произойдет , не на самом деле делать это.
... -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/{}’
( -exec ... \;
хотя и работает с )
/path/to/{}
но я не могу найти ни одной версии, где она работает, поэтому я адаптировал решение. Спасибо
С оболочкой bash вы можете запросить расширение каждого каталога с помощью globstar
опции:
shopt -s globstar
а затем скопируйте каталоги с помощью цикла:
for dir in **/
do
mkdir -p /path/to/dest/"$dir"
done
... или если бы вы думали, что они все подойдут в течение одного звонка mkdir
:
set -- **/
mkdir -- "${@/#//path/to/dest/}"
Это синтаксис массива bash, который гласит: «возьмите каждый элемент $@
массива и замените начало каждого из них на /path/to/dest/
.
Я не знаю, ls
как напрямую получить вывод в виде списка расширений. Если вы попытаетесь втиснуть вывод **/
расширения в расширение фигурной скобки, вам нужно быть осторожным:
{
или ${
последовательностиЯ бы не рекомендовал это.
Этот вопрос является дубликатом кросс-сайта /superuser/1389580/copy-directory-structure-only-at-year-end
Этот вид задачи является классическим вариантом использования для 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)
Вышеприведенное создает все каталоги, под new-tree
которыми присутствовали old-tree
. mtree
однако не устанавливает метки времени для вновь создаваемых каталогов, поэтому результирующее дерево выглядит так:
$ 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
Если вы предпочитаете, чтобы new-tree
временные метки совпадали с указанными old-tree
, просто запустите mtree
снова. Поскольку каталоги уже существуют, mtree
изменит временные метки в соответствии со спецификацией источника:
$ 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
виду, что не каждая реализация поддерживает интерполяцию{}
в другую строку.