Jawaban:
Coba ini,
cd /source/dir/path
find . -type d -exec mkdir -p -- /destination/directory/{} \;
. -type d
Untuk membuat daftar direktori di jalur saat ini secara rekursif.mkdir -p -- /destination/directory/{}
buat direktori di tujuan. Ini bergantung pada find
yang mendukung perluasan {}
di tengah kata argumen.
/source/dir/path
, maka ini mungkin gagal dengan kesalahan "daftar argumen terlalu panjang" ketika shell mencoba memanggil find
dengan perluasan *
. Lebih baik gunakan saja di .
sana. Juga, sebagian besar find
implementasi memungkinkan {}
untuk digunakan bahkan ketika digabungkan dengan string lain, tetapi itu tidak universal.
.
Alih-alih *
dalam hal ini. (Menggunakan xarg untuk kinerja dan keamanan mungkin akan memerlukan skrip eksternal untuk path concatenation)
Menggunakan rsync
:
rsync -a --include='*/' --exclude='*' /some/path/dir/ dir
Ini akan menciptakan kembali struktur direktori /some/path/dir
seperti dir
pada direktori saat ini, tanpa menyalin file apa pun.
Direktori apa pun yang ditemukan di jalur sumber akan dibuat pada target karena pola penyertaan, tetapi hal lain akan dikecualikan. Sebagai efek samping dari penggunaan -a
( --archive
), Anda akan mendapatkan cap waktu yang sama pada semua subdirektori dalam target seperti pada sumber. Ini juga berfungsi untuk membuat struktur direktori lokal dari direktori jarak jauh (dan sebaliknya).
rsync
!
Anda dapat menggunakan find
untuk melintasi struktur sumber dan memanggil mkdir
setiap direktori yang ditemuinya.
Contoh ini, menggunakan find
, akan menyalin struktur direktori Anda dari foo
ke/tmp/another/
( cd foo && find -type d -exec sh -c 'for d do mkdir -p "/tmp/another/$d"; done' sh {} + )
The exec
Loop membangun set direktori di bawahnya foo
, yang kemudian diteruskan ke mkdir
. Jika Anda tidak memiliki versi find
yang mengerti, +
Anda dapat menggunakannya \;
dengan biaya efisiensi. Gantikan mkdir
dengan echo mkdir
untuk melihat apa yang akan terjadi tanpa benar-benar melakukannya.
... -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/{}’
(itu bekerja dengan baik -exec ... \;
)
/path/to/{}
tetapi saya sekarang tidak dapat menemukan versi mana pun yang berfungsi sehingga saya telah mengadaptasi solusinya. Terima kasih
Dengan bash shell, Anda bisa memintanya untuk perluasan setiap direktori dengan globstar
opsi:
shopt -s globstar
dan kemudian salin direktori dengan lingkaran:
for dir in **/
do
mkdir -p /path/to/dest/"$dir"
done
... atau jika Anda pikir semuanya akan cocok dalam satu panggilan ke mkdir
:
set -- **/
mkdir -- "${@/#//path/to/dest/}"
Itu sintaks bash array yang mengatakan: "ambil setiap elemen $@
array dan gantikan awal dari masing-masingnya/path/to/dest/
.
Saya tidak mengetahui cara untuk mendapatkan ls
output secara langsung sebagai daftar ekspansi brace. Jika Anda mencoba memijat output **/
ekspansi menjadi ekspansi brace, Anda harus berhati-hati untuk:
{
atau${
urutanSaya tidak akan merekomendasikannya.
Pertanyaannya adalah duplikat lintas-situs /superuser/1389580/copy-directory-structure-only-at-year-end
Jenis tugas ini adalah kasus penggunaan klasik untuk 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)
Di atas membuat semua direktori di bawah new-tree
yang ada di bawah old-tree
. mtree
tidak menetapkan cap waktu pada direktori yang baru dibuat, sehingga pohon yang dihasilkan terlihat seperti ini:
$ 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
Jika Anda lebih suka new-tree
cap waktu cocok dengan yang ada di old-tree
, cukup jalankan mtree
lagi. Karena direktori sudah ada, mtree
akan mengubah stempel waktu agar sesuai dengan spesifikasi sumber:
$ 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
mendukung interpolasi{}
ke string lain.