Ответы:
Попробуй это,
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виду, что не каждая реализация поддерживает интерполяцию{}в другую строку.