Câu trả lời:
Thử cái này,
cd /source/dir/path
find . -type d -exec mkdir -p -- /destination/directory/{} \;
. -type d
Để liệt kê các thư mục trong đường dẫn hiện tại đệ quy.mkdir -p -- /destination/directory/{}
tạo thư mục tại đích. Điều này phụ thuộc vào một find
hỗ trợ mở rộng {}
ở giữa một từ đối số.
/source/dir/path
đó, thì điều này có thể thất bại với lỗi "danh sách đối số quá dài" khi shell cố gắng gọi find
với sự mở rộng của *
. Tốt hơn là chỉ sử dụng .
ở đó. Ngoài ra, hầu hết các find
triển khai cho phép {}
được sử dụng ngay cả khi được nối với một chuỗi khác, nhưng nó không phổ biến.
.
Thay vì *
trong trường hợp này. (Sử dụng xarg cho hiệu suất và bảo mật có thể sẽ cần một tập lệnh bên ngoài để nối đường dẫn)
Sử dụng rsync
:
rsync -a --include='*/' --exclude='*' /some/path/dir/ dir
Điều này sẽ tạo lại cấu trúc thư mục /some/path/dir
như dir
trong thư mục hiện tại, mà không sao chép bất kỳ tệp nào.
Bất kỳ thư mục nào gặp phải trong đường dẫn nguồn sẽ được tạo tại mục tiêu do mẫu bao gồm, nhưng mọi thứ khác sẽ bị loại trừ. Là một tác dụng phụ của việc sử dụng -a
( --archive
), bạn sẽ nhận được cùng dấu thời gian trên tất cả các thư mục con trong mục tiêu như trong nguồn. Điều này cũng hoạt động để tạo cấu trúc thư mục cục bộ từ các thư mục từ xa (và ngược lại).
rsync
!
Bạn có thể sử dụng find
để duyệt qua cấu trúc nguồn và gọimkdir
cho mỗi thư mục mà nó đáp ứng.
Ví dụ này, sử dụng find
, sẽ sao chép cấu trúc thư mục của bạn từ foo
đến/tmp/another/
( cd foo && find -type d -exec sh -c 'for d do mkdir -p "/tmp/another/$d"; done' sh {} + )
Các exec
vòng lặp xây dựng lên các thiết lập của thư mục bên dưới foo
, sau đó được truyền cho mkdir
. Nếu bạn không có phiên bản find
hiểu rằng +
bạn có thể sử dụng \;
với chi phí hiệu quả. Thay thế mkdir
bằng echo mkdir
để xem những gì sẽ xảy ra mà không thực sự làm việc đó.
... -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 ... \;
mặc dù nó hoạt động với )
/path/to/{}
nhưng bây giờ tôi không thể tìm thấy bất kỳ phiên bản nào hoạt động nên tôi đã điều chỉnh giải pháp. Cảm ơn bạn
Với bash shell, bạn có thể yêu cầu nó mở rộng mọi thư mục với globstar
tùy chọn:
shopt -s globstar
và sau đó sao chép các thư mục với một vòng lặp:
for dir in **/
do
mkdir -p /path/to/dest/"$dir"
done
... hoặc nếu bạn nghĩ rằng tất cả chúng đều phù hợp trong một cuộc gọi tới mkdir
:
set -- **/
mkdir -- "${@/#//path/to/dest/}"
Đó là cú pháp mảng bash có nội dung: "lấy mọi phần tử của $@
mảng và thay thế phần đầu của mỗi phần tử bằng /path/to/dest/
.
Tôi không biết cách để có được ls
đầu ra trực tiếp như một danh sách mở rộng cú đúp. Nếu bạn đã cố gắng xoa bóp đầu ra của việc **/
mở rộng thành mở rộng niềng răng, bạn sẽ cần phải cẩn thận:
{
hoặc ${
trình tựTôi sẽ không đề nghị nó.
Câu hỏi là một bản sao chéo của /superuser/1389580/copy-directory-structure-only-at-year-end
Loại nhiệm vụ này là một trường hợp sử dụng cổ điển cho 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)
Ở trên tạo ra tất cả các thư mục theo new-tree
đó đã có mặt dưới old-tree
. mtree
tuy nhiên, không đặt dấu thời gian trên các thư mục mới được tạo, do đó, cây kết quả trông như thế này:
$ 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
Nếu bạn muốn có new-tree
dấu thời gian khớp với những dấu trong old-tree
, chỉ cần chạy mtree
lại. Vì các thư mục đã tồn tại, mtree
sẽ sửa đổi dấu thời gian để phù hợp với đặc tả nguồn:
$ 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
hỗ trợ phép nội suy{}
thành một chuỗi khác.