Tạo cùng một thư mục con trong thư mục khác


8

Tôi có một thư foomục với thư mục con. Tôi muốn tạo cùng tên thư mục con trong thư mục khác mà không cần sao chép nội dung của chúng. Làm thế nào để tôi làm điều này?

Có cách nào để có được lsđầu ra như một danh sách mở rộng cú đúp?

Câu trả lời:


11

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ố.


6
Điều này có thể phá vỡ nếu bất kỳ tên tệp hoặc thư mục ở cấp cao nhất bắt đầu bằng dấu gạch ngang. Nó cũng bỏ qua các thư mục bắt đầu bằng dấu chấm. Cuối cùng, lưu ý rằng không phải mọi triển khai đều findhỗ trợ phép nội suy {}thành một chuỗi khác.
roaima

1
Và nó không có khả năng mở rộng - sẽ mất nhiều thời gian nếu có hàng triệu thư mục.
Arkadiusz Drabchot

6
Nếu có nhiều thứ trong /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.
Kusalananda

1
Bạn có thể sử dụng .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)
eckes

24

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).


Câu trả lời là gần như luôn luôn rsync!
Arronical

8

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 đó.


1
Hoặc với vòng lặp rõ ràng,... -exec sh -c 'for dirpath do mkdir -p "/some/path/$dirpath"; done' sh {} +
Kusalananda

chính xác với GNU find (4.7.0-git) điều này dường như không hoạt động: find: In ‘-exec ... {} +’ the ‘{}’ must appear by itself, but you specified ‘/tmp/another/{}’( -exec ... \;mặc dù nó hoạt động với )
ilkkachu

Kusalananda, ngẫu hứng thực hiện, cảm ơn bạn
roaima

Ilkkachu Tôi chắc chắn tôi đã thử nghiệm /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
roaima

3

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:

  • thoát khỏi bất kỳ dấu phẩy nào trong đầu ra
  • thoát khỏi bất kỳ {hoặc ${trình tự
  • đảm bảo chuỗi kết quả không vượt quá không gian đối số dòng lệnh có sẵn

Tôi sẽ không đề nghị nó.


2

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.