Làm cách nào để tạo một thư mục trong tất cả các thư mục con?


34

Giả sử tôi có một cấu trúc thư mục như thế này:

$ [~ / thực hành] ls
ABCD/

Bây giờ tôi muốn tạo một thư mục tmp1trong tất cả các thư mục con practicevà tôi làm điều này:

$ [~ / thực hành] mkdir * / tmp1
mkdir: không thể tạo thư mục `* / tmp1 ': Không có tệp hoặc thư mục như vậy

Sau đó, tôi thử -pchuyển đổi và tôi kết thúc với một thư mục có tên là *thư mục contmp1

$ [~ / thực hành] mkdir -p * / tmp1

$ [~ / thực hành] ls
*/ ABCD/

Tôi biết việc sử dụng -pchuyển đổi là tạo nhiều thư mục không tồn tại. Tôi chỉ nghĩ rằng nó có thể giúp đỡ.

Làm cách nào để tạo tmp1trong tất cả các thư mục con cùng một lúc?

Nếu điều này có thể được thực hiện, làm thế nào để mở rộng nó để tạo \tmp1, \tmp2, \tmp3trong \a, \b\ccùng một lúc?

Chỉnh sửa: tôi đã bỏ lỡ nói đến là thư mục không phải là đơn giản và theo thứ tự, như a, b, cvv, và các thư mục được tạo ra không nhất thiết phải như tmp1, tmp2.

$ [~ / thực hành] ls
chó / mèo / chuột /

Trong họ, tôi muốn có một cái gì đó như

$ [~ / thực hành] ls *
chó:
đỏ xanh/

con mèo:
đỏ xanh/

con chuột:
đỏ xanh/

1
Đưa ra câu trả lời của Christopher , bạn nên làm rõ liệu "tạo \ tmp1, \ tmp2, \ tmp3 trong \ a, \ b và \ c" có dẫn đến tổng cộng 3 hoặc 9 thư mục con hay không.
thao tác

@manatwork: Đó là một điểm tốt. Nó sẽ tạo ra 9 thư mục con.
Animesh

Điều này giúp tôi giải quyết vấn đề không gian trong tên của thư mục sudo find ./ -depth -type d -exec echo '"{} / RCS"' \;

Câu trả lời:


44

Với sự hả hê :

for dir in */; do mkdir -- "$dir/tmp1"; done

CHÚ THÍCH

  • Tôi chỉ xử lý các thư mục (bao gồm cả liên kết tượng trưng đến thư mục) với một chút hack sử dụng */như một quả địa cầu
  • Nếu bạn muốn tạo nhiều thư mục con cùng một lúc:

    for dir in */; do mkdir -- "$dir"/{tmp1,foo,bar,qux}; done


Tôi có thể làm for i in */; do mkdir "$i/itemone" "$i/itemtwo"; donecho nhiều tên thư mục không theo thứ tự không?
Animesh

Tôi đã thử nghiệm điều này và nó là rất nhiều có thể. Cảm ơn.
Animesh

Xem bài đăng đã được chỉnh sửa của tôi
Gilles Quenot

1
Mở rộng cú đúp không được thực hiện trong chuỗi trích dẫn.
thao tác

Vâng, cảm ơn, bài đăng được chỉnh sửa bởi Stephane Chazelas phù hợp ...
Gilles Quenot

10

[...] Làm cách nào để tôi mở rộng nó để tạo \ tmp1, \ tmp2, \ tmp3 trong \ a, \ b và \ c cùng một lúc?

 mkdir {a,b,c}/tmp{1,2,3}

10

Với GNU hoặc BSD * tìm:

find -mindepth 1 -maxdepth 1 -type d -exec mkdir {}/newdir \;

hoặc sử dụng mở rộng tham số:

dirs=(*/)
mkdir -- "${dirs[@]/%/newdir}"

* Bao gồm OS X


2
Với cú pháp tìm tiêu chuẩn:find . -name . -o -prune -type d -exec sh -c 'exec mkdir "$1/newdir"' sh {} \;
Stéphane Chazelas

1
Cũng lưu ý sự khác biệt giữa hai giải pháp: giải pháp đầu tiên bao gồm các thư mục ẩn, giải pháp thứ hai sẽ thêm một newdir trong các thư mục được liên kết bởi bất kỳ liên kết tượng trưng nào trong thư mục hiện tại.
Stéphane Chazelas

6

Tắt chủ đề kể từ khi bạn đề cập bash, nhưng đối với bản ghi, với zsh, bạn sẽ làm:

dirs=(*(/))
mkdir -- $^dirs/tmp1

$^varbật mở rộng giống như cú đúp để mở rộng mảng. Đó là gợi nhớ rccủa ^nhà điều hành và trong rc(hoặc dẫn xuất của nó es), bạn muốn viết nó:

dirs=(*/)
mkdir -- $dirs^tmp1

Tuy nhiên, lưu ý (và áp dụng tương tự cho các giải pháp bash được đưa ra ở đây) rằng trong giải pháp RC dirscũng sẽ chứa các liên kết tượng trưng đến các thư mục. Trong giải pháp zsh, thay đổi *(/)thành *(-/)nếu bạn muốn bao gồm các liên kết tượng trưng đến thư mục.


+1 cho quan điểm của bạn về symlink! Hành vi này có thể được mong muốn, nhưng khiếu nại của mkdir về việc tạo một thư mục trùng lặp có thể được loại bỏ bằng -pcờ.
kojiro

4

Có khả năng, lặp qua các thư mục mẹ:

for d in */; do mkdir "$d/red" "$d/blue"; done

Thêm --sau mkdirnếu bạn có thể có thư mục có tên bắt đầu bằng -.

Trong zsh, bạn có thể thực hiện nó trong một lệnh duy nhất với e vòng loại toàn cầu :

mkdir *(/e\''REPLY=($REPLY/{red,blue})'\')

nhưng nhanh hơn để gõ lệnh này thành hai lệnh:

d=(*(/)); mkdir $^d/{red,blue}

1
Trên một trang web có ý nghĩa là một tài liệu tham khảo, tôi muốn nói " mkdir -- whateverbỏ qua -- nếu bạn có ý định mở rộng bất cứ điều gì có thể được coi là tùy chọn cho mkdirlệnh." Không có điểm nào để bỏ qua --ở đây. Nó có thể không phải là một vấn đề trong trường hợp của OP, nhưng nó là một trong trường hợp chung. Tôi nghĩ rằng chúng ta có nhiệm vụ dạy cú pháp chính xác và an toàn ở đây.
Stéphane Chazelas

@StephaneChazelas Trong bối cảnh kịch bản, tôi luôn đặt tất cả các --trích dẫn cần thiết cũng như cảnh báo lớn khi các dòng mới không được hỗ trợ. Trong ngữ cảnh dòng lệnh, tôi thích hiển thị phiên bản nhanh hoạt động trên thực tế trước và phiên bản chống đạn như một phần bổ sung.
Gilles 'SO- ngừng trở nên xấu xa'


1

Sự thay đổi trong câu trả lời của sputnick giúp tránh các tệp không phải là thư mục:

for x in *; do if [ -d "$x" ]; then mkdir "$x/tmp1"; fi; done

Tôi chỉ coi các thư mục, đó là tất cả sự kỳ diệu ...
Gilles Quenot

tuyệt, hiểu rồi;)
goldilocks

2
Có nên như if [ -d "$x" ];…vậy không?
kojiro

Vâng. Tôi thực tế không bao giờ có không gian trong tên tập tin và có xu hướng quên những thứ đó ...
goldilocks

1

Đây là một điểm tốt từ Unix Masters cũ (đã được thử nghiệm trên FreeBSD 10.1) nếu bạn muốn kiểm soát phiên bản (với kiểm tra RCS bị khóa: ci -l với một nhận xét ngắn gọn là ir: để phát hành lần đầu) các tệp cấu hình / etc / * của bạn vào ~ / .his / etc

sudo rsync -av /etc/ ~/.his
sudo find -d ~/.his/etc -type d -exec echo '{}/RCS' \; | xargs sudo mkdir -p
sudo find -d ~/.his/etc \! -name "RCS" | xargs sudo ci -l -mir -t-ir

Tôi không thấy câu trả lời này của OP
Archemar 28/03/2015

1

Nên là \! tên "RCS" và nó hoạt động tốt nhất trong lần đăng nhập đầu tiên.

sudo tìm ~ / .his / etc \! -name "RCS" -ls

sudo tìm -d ~ / .his / etc \! -Tên "RCS" | xargs sudo ci -l -mir -t-ir

Cái cuối cùng này cũng hoạt động rất tốt cho cjeck trong phần lọc tất cả nội dung RCS trên tên tệp:

sudo find -d ~ / .his / etc -type f | grep -v RCS | xargs sudo ci -l -mir -t-ir


1

đây là một sự giúp đỡ tuyệt vời cho tôi tôi có nhu cầu tạo một tập hợp các thư mục con trong nhiều thư mục và đại loại như:

!/bin/sh

cd /dest/cont

for dir in */*/; do
    mkdir -p -- $dir/{FB,Video,Audio,proj};
done

làm việc tuyệt vời trừ khi gặp một khoảng trắng Có cách nào để bỏ qua khoảng trắng trong */*/phần tranh luận không?

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.