การสร้างไดเรกทอรีจำนวนมากโดยใช้ mkdir


14

mkdirผมอยากจะสร้างไดเรกทอรีมากใช้ แต่ละชื่อไดเรกทอรีจะประกอบด้วยคำนำหน้า (สตริง) และดัชนี (จำนวนเต็ม) สมมติว่าฉันต้องการให้คำนำหน้าเป็น "s" และดัชนีอยู่ในช่วงตั้งแต่ 1 ถึง 50 ซึ่งหมายความว่าฉันต้องการสร้างไดเรกทอรีชื่อ:

s1,, s2... s49,,s50

มีวิธีการทำสิ่งนี้โดยอัตโนมัติโดยใช้mkdirหรือไม่? ขอบคุณที่สละเวลา.


2
คุณใช้เปลือกไหน
Francesco Turco

@FrancescoTurco bashฉันใช้ ขอขอบคุณสำหรับเวลาของคุณ!
Andrew

3
FYI ฉันคิดว่ามันมากมีประโยชน์มากขึ้นที่จะใช้ดัชนีความกว้างคงที่เช่น: s01, s02, ... ,s49 s50หากฉันใช้ดัชนีความกว้างคงที่/bin/lsเกือบทุกครั้งที่ฉันต้องการสั่งซื้อ
Rob

คำตอบ:


32

คุณสามารถทำได้ด้วยเชลล์สคริปต์

Pure sh - สิ่งนี้จะใช้งานได้บนเปลือกหอย POSIX BIX:

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

หากคุณต้องการสร้างไดเรกทอรีจำนวนมากคุณสามารถทำให้สคริปต์เร็วขึ้นได้โดยลดลงในการโทรครั้งเดียวmkdirรวมถึงการใช้ shell builtins สำหรับการทดสอบและ arithmetics แบบนี้:

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 หรือ bash ทำให้มันง่ายขึ้นมาก แต่ฉันควรจะชี้ให้เห็นว่านี่ไม่ได้อยู่ในตัวmkdirและอาจไม่สามารถใช้งานได้ในกระสุนอื่น ๆ สำหรับกรณีที่มีขนาดใหญ่กว่าก็อาจได้รับผลกระทบจากข้อ จำกัด เกี่ยวกับจำนวนหรือขนาดทั้งหมดของข้อโต้แย้งที่อาจถูกส่งผ่านไปยังคำสั่ง

mkdir s{1..50}

3
+1 นี่มันเยี่ยมมาก! ฉันต้อง nitpick เกี่ยวกับสิ่งหนึ่งแม้ว่า: n=$(( n + 1 ))จะเป็นเช่นเดียวกับ POSIX อย่างเคร่งครัดและจะไม่เสียค่าใช้จ่ายกับคุณ
kojiro

@rahmu [[คำหลักไม่ใช่ POSIX (ไม่พูดถึงว่า[ เป็น builtin เปลือกหอยที่ทันสมัยมาก.)
Kojiro

@kojiro: [[ทำงานบนของฉันksh88(ซึ่งมาก่อนbash) ดังนั้นฉันคิดว่ามันเป็น POSIX ฉันไม่พบการกล่าวถึงในPOSIX specดังนั้นฉันเชื่อว่าคุณพูดถูก ขอบคุณสำหรับข้อมูล!
rahmu

ฉันคิดเกี่ยวกับการเพิ่มเวอร์ชันโดยใช้การขยายแบบเลขคณิต แต่ต้องการ จำกัด "pure sh" ให้กับสิ่งต่าง ๆ ที่ใช้กับ POSIX รุ่นก่อนได้เช่นกัน ฉันยังไม่ได้พูดถึง seq ด้วยเหตุผลเดียวกัน - ถ้าคุณมี seq คุณอาจทุบตี ตัวอย่างลูปยังดีสำหรับการข้ามข้อ จำกัด การโต้แย้งสำหรับไดเรกทอรีจำนวนมากซึ่งหมายความว่ามีสถานที่for i in {range}สำหรับผู้ใช้เชลล์ขั้นสูง
Random832

คำใบ้ zsh ในตอนท้ายนั้นยอดเยี่ยมมากมันช่วยฉันประหยัดเวลาได้มาก!
Jase

33
  • หนึ่ง

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

    mkdir s{1..50}

    ตัวเลือกนี้ทำงานในbash , zshและksh93

  • สาม

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

4
ทำไมคุณถึงใช้หนึ่งในสอง?
เควิน

7
คุณอาจต้องการที่จะทำมากขึ้นด้วยกว่าเพียงแค่การทำเช่นไดเรกทอรี$i mkdir s$i ; echo $i > s$i/$iนอกจากนี้ One ยังเป็นตัวอย่างที่ดีและเรียบง่ายของการใช้ for for loop ใน bash ... บนเว็บไซต์เช่นนี้มันไม่น่าเป็นไปได้เลยที่ผู้ใช้มือใหม่จะเห็นและคิดว่า "ดีฉันไม่ทราบว่าคุณสามารถทำได้ "---> การรู้แจ้ง
cas

1
@rahmu เป็นคุณลักษณะที่พบใน Bash / Zsh (อาจเป็น ksh93 ด้วย) ไม่จำเป็นต้องลงคะแนน
helpermethod

3
@rahmu: ฉันคิดว่าควรพิจารณาว่าคำตอบของ jhonathan แก้ไขปัญหาด้วยเปลือกของ OP (ทุบตี) ไม่จำเป็นต้องอยู่กับคนอื่น
Francesco Turco

4
@ เควินในขณะที่มันไม่น่าจะเป็นปัญหาสำหรับห้าสิบถ้าคุณมีห้าร้อยไดเรกทอรีที่จะทำให้คุณอาจกังวลเกี่ยวกับข้อ จำกัด การโต้แย้ง
Random832

10

คำตอบที่ซับซ้อนมากมายที่นี่ แต่ทุบตีทำให้มันง่ายจริงๆ แน่นอนว่าโซลูชัน POSIX บริสุทธิ์ทำงานได้ แต่ทำไมไม่ลองใช้ประโยชน์จากbashเชลล์ที่คุณใช้อยู่ล่ะ? คุณสามารถทำได้อย่างง่ายดายด้วยการขยายรั้ง :

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

หรือถ้าคุณต้องการตัวเลขที่ไม่มีเบาะรอง (ซึ่งจะเป็นการดีกว่าสำหรับการเรียงลำดับ):

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

หรือ:

mkdir s$(seq -s ' s' -w 1 50)- สังเกตว่าสตริง 's' อยู่ตรงหน้า$()โดยที่ไม่มีไดเรกทอรีแรกที่สร้างจะเป็น '01' แทนที่จะเป็น 's01'

และในที่สุดก็: mkdir $(printf "s%02i " $(seq 1 50))

seq มาจาก GNU Coreutils

อย่างแปลก, seq's --formatหรือ-fตัวเลือกอนุญาตเฉพาะประเภทจุดลอยของ printf (เช่น f และ g. ยังเป็นรูปแบบเลขฐานสิบหกจุดที่แปลกประหลาดที่ฉันไม่เคยพบการใช้งานใด ๆ สำหรับ) ฉันมีความคิดว่าทำไมไม่มี. มันจะดีถ้ามันรองรับprintf(3)ประเภทตัวเลขอื่น ๆเช่นจำนวนเต็ม (d, i), ฐานแปด (o, U) หรือฐานสิบหก (x, X)

อย่างไรก็ตามรูปแบบสองครั้งที่มีความแม่นยำทศนิยม 0 เช่น%.0fหรือ%02.0fใกล้พอที่จะเป็นจำนวนเต็มเพื่อจุดประสงค์นี้

$ seq - ช่วยเหลือ
การใช้งาน: seq [OPTION] ... LAST
  หรือ: seq [OPTION] ... เป็นครั้งแรก
  หรือ: seq [OPTION] ... การบุกรุกครั้งแรก
พิมพ์ตัวเลขจาก FIRST ถึง LAST เป็นขั้นตอน INCREMENT

  -f, - รูปแบบ = FORMAT ใช้รูปแบบลอยตัว printf สไตล์ FORMAT
  -s, --separator = STRING ใช้ STRING เพื่อแยกตัวเลข (ค่าเริ่มต้น: \ n)
  -w, - ความกว้างเท่ากันเท่ากับความกว้างโดยการเติมด้วยเลขศูนย์นำหน้า
      - ช่วยแสดงความช่วยเหลือและออก
      - ข้อมูลรุ่นส่งออกและออก

หากไม่ได้ระบุ FIRST หรือ INCREMENT จะมีค่าเริ่มต้นเป็น 1 นั่นคือ
ละเว้น INCREMENT จะมีค่าเริ่มต้นเป็น 1 แม้ว่า LAST จะเล็กกว่า FIRST แรก
FIRST, INCREMENT และ LAST ถูกตีความว่าเป็นค่าทศนิยม
INCREMENT มักจะเป็นค่าบวกหาก FIRST นั้นเล็กกว่า LAST และ
INCREMENT มักจะเป็นค่าลบถ้า FIRST มากกว่า LAST
รูปแบบจะต้องเหมาะสมสำหรับการพิมพ์หนึ่งอาร์กิวเมนต์ประเภท `คู่ ';
มันเริ่มต้นที่% .PRF ถ้าเป็นครั้งแรกที่ INCREMENT และ LAST เป็นจุดคงที่ทั้งหมด
ตัวเลขทศนิยมที่มีความแม่นยำสูงสุด PREC และเป็นอย่างอื่นถึง% g

ดูเพิ่มเติมที่: http://www.gnu.org/software/coreutils/manual/html_node/seq-invocation.html


{1,50}หรือ{01,50}(สำหรับ zero-padding) นั้นง่ายกว่าและเข้าใจได้ง่ายกว่า
เควิน

1
จริง ... ถ้าคุณใช้ทุบตีมากกว่าดวลจุดโทษ นั่นเป็นเหตุผลที่ฉัน upvoted @ คำตอบของ Random832 มันเป็นคำตอบที่ดี การใช้ seq เป็นคำตอบที่มีประโยชน์เช่นกัน
cas

4

นี่คือโซลูชัน POSIX sh ที่ใช้การเรียกซ้ำ

makedirs() {
  [ "$1" -gt 0 ] || return
  mkdir "s$1"
  makedirs $(( $1 - 1 ))
}
$ makedirs 9
$ ls
s1  s2  s3  s4  s5  s6  s7  s8  s9
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.