Tạo nhiều thư mục bằng mkdir


13

Tôi muốn tạo nhiều thư mục bằng cách sử dụng mkdir. Mỗi tên thư mục sẽ bao gồm một tiền tố (một chuỗi) và một chỉ mục (một số nguyên). Giả sử rằng tôi muốn tiền tố là "s" và các chỉ số nằm trong khoảng từ 1 đến 50. Điều này có nghĩa là tôi muốn tạo các thư mục có tiêu đề:

s1, s2, ..., s49,s50

Có cách nào để làm điều này tự động bằng cách sử dụng mkdir? Cảm ơn vì đã dành thời gian cho tôi.


2
Bạn đang sử dụng vỏ nào?
Francesco Turco

@FrancescoTurco Tôi đang sử dụng bash. Cảm ơn bạn đã dành thời gian!
Andrew

3
FYI, tôi thấy nó nhiều hữu ích hơn để sử dụng các chỉ số chiều rộng cố định, như: s01, s02, ..., s49, s50. Nếu tôi sử dụng các chỉ số có chiều rộng cố định, /bin/lshầu như luôn tạo ra thứ tự tôi muốn.
Cướp

Câu trả lời:


31

Bạn có thể làm điều này với một kịch bản shell.

Pure sh - điều này sẽ hoạt động ngay cả trên các vỏ bourne trước POSIX:

n=1;
max=50;
while [ "$n" -le "$max" ]; do
  mkdir "s$n"
  n=`expr "$n" + 1`;
done

Nếu bạn muốn tạo số lượng lớn thư mục, bạn có thể tạo tập lệnh nhanh hơn bằng cách giảm nó thành một cuộc gọi mkdircũng như sử dụng các nội dung shell để kiểm tra và mỹ phẩm. Như thế này:

n=1
max=50
set -- # this sets $@ [the argv array] to an empty list.

while [ "$n" -le "$max" ]; do
    set -- "$@" "s$n" # this adds s$n to the end of $@
    n=$(( $n + 1 ));
done 

mkdir "$@"

Zsh, ksh93 hoặc bash làm cho việc này dễ dàng hơn nhiều, nhưng tôi nên chỉ ra rằng nó không được tích hợp mkdirvà có thể không hoạt động trong các shell khác. Đối với các trường hợp lớn hơn, nó cũng có thể bị ảnh hưởng bởi các giới hạn về số lượng hoặc tổng kích thước của các đối số có thể được truyền cho một lệnh.

mkdir s{1..50}

3
+1 Điều này thật tuyệt! Mặc dù vậy, tôi phải hiểu về một điều: n=$(( n + 1 ))sẽ hoàn toàn giống như POSIX và sẽ không khiến bạn phải trả giá.
kojiro

@rahmu [[từ khóa không phải là POSIX. (Chưa kể đó [ một vỏ được tích hợp trong nhiều lớp vỏ hiện đại.)
kojiro

@kojiro: [[hoạt động trên ksh88(trước đó bash) của tôi vì vậy tôi cho rằng đó là POSIX. Tôi không thể tìm thấy bất kỳ đề cập nào về nó trong thông số POSIX vì vậy tôi tin rằng bạn đúng. Cảm ơn bạn về thông tin!
rahmu

Tôi đã nghĩ đến việc thêm một phiên bản bằng cách sử dụng mở rộng số học, nhưng muốn giới hạn "thuần sh" đối với những thứ sẽ hoạt động trên các phiên bản tiền POSIX. Tôi cũng không đề cập đến seq vì lý do tương tự - nếu bạn có seq, có lẽ bạn đã bị bash. Ví dụ về vòng lặp cũng tốt cho việc bỏ qua các giới hạn đối số cho số lượng thư mục lớn hơn, điều đó cũng có nghĩa là có một nơi dành for i in {range}cho người dùng trình bao nâng cao.
Random832

Các gợi ý zsh ở cuối là tuyệt vời, nó đã tiết kiệm cho tôi rất nhiều thời gian!
Jase

33
  • Một

    for i in {1..50}; do
      mkdir s"$i"
    done
  • Hai

    mkdir s{1..50}

    Tùy chọn này hoạt động trong bash , zshksh93

  • Số ba

    mkdir $(printf "s%02i " $(seq 1 50))

4
Tại sao bạn sẽ sử dụng một trên hai?
Kevin

7
bạn có thể muốn làm nhiều hơn với $ichỉ tạo một thư mục, vd mkdir s$i ; echo $i > s$i/$i. Ngoài ra, One là một ví dụ đơn giản, đẹp mắt về việc sử dụng vòng lặp for trong bash ... trên một trang web như thế này, người dùng mới làm quen không thể nhìn thấy nó và nghĩ rằng "thật tuyệt, tôi không nhận ra bạn có thể làm điều đó "---> giác ngộ.
cas

1
@rahmu Đó là một tính năng được tìm thấy trong Bash / Zsh (có thể là ksh93 nữa). Không cần downvote.
helpermethod

3
@rahmu: Tôi nghĩ người ta chỉ nên xem xét nếu câu trả lời của jhonathan khắc phục vấn đề với vỏ OP (bash), không nhất thiết phải với người khác.
Francesco Turco

4
@Kevin trong khi nó không có khả năng là vấn đề trong năm mươi, nếu bạn có năm trăm thư mục để khiến bạn có thể lo lắng về giới hạn đối số.
Random832

10

Rất nhiều câu trả lời phức tạp ở đây, nhưng bash làm cho nó thực sự dễ dàng. Chắc chắn, giải pháp POSIX thuần túy hoạt động, nhưng tại sao không tận dụng lợi thế của bashvỏ bạn đang sử dụng, dù sao đi nữa? Bạn có thể làm điều này dễ dàng với mở rộng cú đúp :

% mkdir -v s{1..10} && ls -1d s{1..10}                                   (09-24 17:37)
mkdir: created directory `s1'
mkdir: created directory `s2'
mkdir: created directory `s3'
mkdir: created directory `s4'
mkdir: created directory `s5'
mkdir: created directory `s6'
mkdir: created directory `s7'
mkdir: created directory `s8'
mkdir: created directory `s9'
mkdir: created directory `s10'
s1
s10
s2
s3
s4
s5
s6
s7
s8
s9

5

mkdir $(seq --format 's%.0f' 1 50)

hoặc nếu bạn muốn số không đệm (sẽ tốt hơn cho việc sắp xếp):

mkdir $(seq --format 's%02.0f' 1 50)

hoặc là:

mkdir s$(seq -s ' s' -w 1 50)- lưu ý chuỗi 's' ngay trước $(), không có nó, thư mục đầu tiên được tạo sẽ chỉ là '01' thay vì 's01'

và cuối cùng: mkdir $(printf "s%02i " $(seq 1 50))

seq là từ GNU Coreutils

thật kỳ lạ, tùy chọn --formathoặc -ftùy chọn của seq chỉ cho phép các loại hình dấu phẩy động của printf (như f và g. cũng là một định dạng hex dấu phẩy động lạ mà tôi chưa bao giờ tìm thấy để sử dụng). Tôi không biết tại sao. Sẽ thật tuyệt nếu nó cũng hỗ trợ các printf(3)loại số khác như số nguyên (d, i), bát phân (o, U) hoặc hex (x, X).

Dù sao, một định dạng kép với độ chính xác thập phân 0 như %.0fhoặc %02.0fđủ gần với một số nguyên cho mục đích này.

$ seq - trợ giúp
Cách sử dụng: seq [TÙY CHỌN] ... CUỐI
  hoặc: seq [TÙY CHỌN] ... CUỐI CÙNG ĐẦU TIÊN
  hoặc: seq [TÙY CHỌN] ... CUỐI CÙNG TĂNG TỐC ĐẦU TIÊN
In số từ FIRST sang LAST, theo các bước TĂNG.

  -f, --format = FORMAT sử dụng FORMAT dấu phẩy động kiểu printf
  -s, --separator = STRING sử dụng CHUINGI để tách các số (mặc định: \ n)
  -w, - cân bằng chiều rộng cân bằng chiều rộng bằng cách đệm với các số 0 đứng đầu
      --hỗ trợ hiển thị trợ giúp này và thoát
      - đảo ngược thông tin phiên bản đầu ra và thoát

Nếu FIRST hoặc INCREMENT bị bỏ qua, nó mặc định là 1. Đó là, một
bỏ qua TĂNG TỐC mặc định là 1 ngay cả khi LAST nhỏ hơn FIRST.
FIRST, INCREMENT và LAST được hiểu là các giá trị dấu phẩy động.
THU NHẬP thường dương nếu FIRST nhỏ hơn LAST và
TĂNG CƯỜNG thường âm nếu FIRST lớn hơn LAST.
FORMAT phải phù hợp để in một đối số kiểu 'double';
nó mặc định là% .PRECf nếu FIRST, INCREMENT và LAST đều là điểm cố định
số thập phân với PREC chính xác tối đa và khác% g.

Xem thêm: http://www.gnu.org/software/coreutils/manual/html_node/seq-invocation.html


{1,50}hoặc {01,50}(đối với phần đệm không) dễ dàng hơn và dễ hiểu hơn nhiều.
Kevin

1
đúng ... nếu bạn đang sử dụng bash chứ không phải sh. đó là lý do tại sao tôi nêu lên câu trả lời của @ Random832. đó là một câu trả lời tốt sử dụng seq cũng là một câu trả lời hữu ích.
cas

4

Để khác biệt, đây là một giải pháp POSIX sh sử dụng đệ quy:

makedirs() {
  [ "$1" -gt 0 ] || return
  mkdir "s$1"
  makedirs $(( $1 - 1 ))
}
$ makedirs 9
$ ls
s1  s2  s3  s4  s5  s6  s7  s8  s9
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.