Respostas:
Tente isso,
cd /source/dir/path
find . -type d -exec mkdir -p -- /destination/directory/{} \;
. -type d
Para listar diretórios no caminho atual recursivamente.mkdir -p -- /destination/directory/{}
criar diretório no destino. Isso se baseia em um find
que suporta expansão {}
no meio de uma palavra de argumento.
/source/dir/path
, então este poderá falhar com uma "lista de argumentos muito longa" erro quando as tentativas de shell para chamar find
com a expansão da *
. Melhor usar apenas .
lá. Além disso, a maioria das find
implementações permite {}
ser usada mesmo quando concatenada com outra sequência, mas não é universal.
.
Em vez de *
neste caso. (Usando xarg para desempenho e segurança provavelmente exigiria um script externo para a concatenação path)
Usando rsync
:
rsync -a --include='*/' --exclude='*' /some/path/dir/ dir
Isso recriaria a estrutura de diretórios /some/path/dir
como dir
no diretório atual, sem copiar nenhum arquivo.
Qualquer diretório encontrado no caminho de origem seria criado no destino devido ao padrão de inclusão, mas qualquer outra coisa seria excluída. Como efeito colateral do uso de -a
( --archive
), você obterá os mesmos carimbos de data e hora em todos os subdiretórios no destino e na origem. Isso também funciona para criar estruturas de diretórios locais a partir de diretórios remotos (e vice-versa).
rsync
!
Você pode usar find
para percorrer a estrutura de origem e chamar mkdir
cada diretório que ele atender.
Este exemplo, usando find
, copiará sua estrutura de diretórios de foo
para/tmp/another/
( cd foo && find -type d -exec sh -c 'for d do mkdir -p "/tmp/another/$d"; done' sh {} + )
O exec
loop cria o conjunto de diretórios abaixo foo
, que é passado para o mkdir
. Se você não tem uma versão find
disso, +
pode usar \;
ao custo da eficiência. Substitua mkdir
por echo mkdir
para ver o que aconteceria sem realmente fazê-lo.
... -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/{}’
(ela não funciona com -exec ... \;
, embora)
/path/to/{}
mas agora não consigo encontrar nenhuma versão em que funcione, por isso adaptei a solução. Obrigado
Com o shell bash, você pode solicitar a expansão de todos os diretórios com a globstar
opção:
shopt -s globstar
e copie os diretórios com um loop:
for dir in **/
do
mkdir -p /path/to/dest/"$dir"
done
... ou se você acha que todos eles se encaixam em uma chamada para mkdir
:
set -- **/
mkdir -- "${@/#//path/to/dest/}"
Essa é a sintaxe do bash array que diz: "pegue todos os elementos do $@
array e substitua o início de cada um deles por /path/to/dest/
.
Não conheço uma maneira de obter ls
saída diretamente como uma lista de expansão de chaves. Se você tentou massagear a saída da **/
expansão em uma expansão de cinta, seria necessário ter cuidado para:
{
ou ${
sequênciaEu não recomendaria.
A pergunta é uma duplicata entre sites de /superuser/1389580/copy-directory-structure-only-at-year-end
Esse tipo de tarefa é um caso de uso clássico para 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)
O acima cria todos os diretórios abaixo new-tree
que estavam presentes em old-tree
. mtree
não define carimbos de data e hora em diretórios recém-criados, portanto, a árvore resultante se parece com isso:
$ 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 você preferir que os new-tree
carimbos de data e hora correspondam aos old-tree
, simplesmente execute mtree
novamente. Como os diretórios já existem, mtree
os timestamps serão modificados para corresponder à especificação de origem:
$ 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
suporta a interpolação de{}
em outra sequência.