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 findhỗ 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 findvớ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 findtriể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/dirnhư dirtrong 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 execvò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 findhiểu rằng +bạn có thể sử dụng \;với chi phí hiệu quả. Thay thế mkdirbằ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 globstartù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. mtreetuy 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-treedấu thời gian khớp với những dấu trong old-tree, chỉ cần chạy mtreelại. Vì các thư mục đã tồn tại, mtreesẽ 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
findhỗ trợ phép nội suy{}thành một chuỗi khác.