มี bash for loop อยู่สองประเภท ตัวหนึ่งใช้คีย์เวิร์ด “in” พร้อมรายการค่า อีกตัวใช้โปรแกรม C เช่น syntax
บทความนี้เป็นส่วนหนึ่งของชุดการสอนทุบตีที่กำลังดำเนินอยู่
ซึ่งจะอธิบายวิธีการ bash for loop ทั้งสองแบบ และให้ตัวอย่าง 12 ตัวอย่างที่แตกต่างกันเกี่ยวกับวิธีใช้ bash for loop ในเชลล์สคริปต์ของคุณ
คั่นบทความนี้ไว้เพื่อใช้อ้างอิงในอนาคต เนื่องจากเป็นบทความเดียวที่คุณ จะต้องอ้างอิงถึงวิธีใช้ bash for loop พร้อมตัวอย่าง
วิธีที่ 1:Bash For Loop โดยใช้ “in” และรายการค่า
ไวยากรณ์:
for varname in list do command1 command2 .. done
ในไวยากรณ์ด้านบน:
- สำหรับ ใน ทำ และเสร็จสิ้น คือคีย์เวิร์ด
- “list” ประกอบด้วยรายการค่าต่างๆ รายการสามารถเป็นตัวแปรที่มีคำหลายคำคั่นด้วยช่องว่าง หาก list หายไปในคำสั่ง for จะใช้พารามิเตอร์ตำแหน่งที่ส่งผ่านไปยังเชลล์
- varname คือชื่อตัวแปรของ Bash
ในแบบฟอร์มนี้ คำสั่ง for จะรันคำสั่งที่อยู่ในเนื้อหา หนึ่งครั้งสำหรับแต่ละรายการในรายการ ตัวอย่างเช่น หากรายการค่ามี 5 รายการ ลูป for จะถูกดำเนินการทั้งหมด 5 ครั้ง หนึ่งครั้งสำหรับแต่ละรายการในรายการ รายการปัจจุบันจากรายการจะถูกเก็บไว้ในตัวแปร "varname" แต่ละครั้งผ่านลูป “varname” นี้สามารถประมวลผลในส่วนของ for loop ได้
วิธีที่ 2:Bash For Loop โดยใช้ C เช่นไวยากรณ์
รูปแบบที่สองของ for loop คล้ายกับ for loop ในภาษาการเขียนโปรแกรม “C” ซึ่งมีสามนิพจน์ (การกำหนดค่าเริ่มต้น เงื่อนไข และการอัปเดต)
for (( expr1; expr2; expr3 )) do command1 command2 .. done
ใน bash ด้านบนสำหรับไวยากรณ์คำสั่ง
- ก่อนการทำซ้ำครั้งแรก จะมีการประเมิน expr1 โดยปกติจะใช้เพื่อเริ่มต้นตัวแปรสำหรับลูป
- คำสั่งทั้งหมดระหว่าง do และ done จะถูกดำเนินการซ้ำๆ จนกว่าค่าของ expr2 จะเป็น TRUE
- หลังจากการวนซ้ำแต่ละครั้งจะมีการประเมิน expr3 ปกติจะใช้เพื่อเพิ่มตัวนับลูป
ตัวอย่าง 12 ตัวอย่างต่อไปนี้แสดงวิธี bash for loops ในรูปแบบต่างๆ
1. ค่าคงที่สำหรับรายการหลังคำสำคัญ “ใน”
ในตัวอย่างต่อไปนี้ รายการของค่า (จันทร์ อังคาร พุธ พฤหัสบดี และศุกร์) จะได้รับโดยตรงหลังจากคีย์เวิร์ด “ใน” ใน bash for loop
$ cat for1.sh i=1 for day in Mon Tue Wed Thu Fri do echo "Weekday $((i++)) : $day" done $ ./for1.sh Weekday 1 : Mon Weekday 2 : Tue Weekday 3 : Wed Weekday 4 : Thu Weekday 5 : Fri
ข้อควรระวัง: รายการค่าไม่ควรคั่นด้วยเครื่องหมายจุลภาค (จันทร์ อังคาร พุธ พฤหัสบดี ศุกร์) เครื่องหมายจุลภาคจะถือว่าเป็นส่วนหนึ่งของค่า กล่าวคือ แทนที่จะใช้ “จ” จะใช้ “จ” เป็นค่าดังตัวอย่างด้านล่าง
$ cat for1-wrong1.sh i=1 for day in Mon, Tue, Wed, Thu, Fri do echo "Weekday $((i++)) : $day" done $ ./for1-wrong1.sh Weekday 1 : Mon, Weekday 2 : Tue, Weekday 3 : Wed, Weekday 4 : Thu, Weekday 5 : Fri
ข้อควรระวัง: รายการค่าไม่ควรอยู่ในเครื่องหมายคำพูดคู่ (“จันทร์ อังคาร พุธ พฤหัสบดี ศุกร์”). หากคุณใส่เครื่องหมายอัญประกาศคู่ ระบบจะถือว่าเป็นค่าเดียว (แทนที่จะเป็น 5 ค่าที่แตกต่างกัน) ดังที่แสดงในตัวอย่างด้านล่าง
$ cat for1-wrong2.sh i=1 for day in "Mon Tue Wed Thu Fri" do echo "Weekday $((i++)) : $day" done $ ./for1-wrong2.sh Weekday 1 : Mon Tue Wed Thu Fri
2. ตัวแปรสำหรับรายการหลังคีย์เวิร์ด “ใน”
แทนที่จะระบุค่าโดยตรงในลูป for คุณสามารถเก็บค่าไว้ในตัวแปร และใช้ตัวแปรในลูป for หลังคีย์เวิร์ด "in" ดังที่แสดงในตัวอย่างต่อไปนี้
$ cat for2.sh i=1 weekdays="Mon Tue Wed Thu Fri" for day in $weekdays do echo "Weekday $((i++)) : $day" done $ ./for2.sh Weekday 1 : Mon Weekday 2 : Tue Weekday 3 : Wed Weekday 4 : Thu Weekday 5 : Fri
ข้อควรระวัง :ตามแนวทางปฏิบัติที่ดีที่สุด คุณควรอ้างอิงตัวแปรทุบตีเสมอเมื่อคุณอ้างอิง มีข้อยกเว้นบางประการสำหรับกฎแนวทางปฏิบัติที่ดีที่สุดนี้ นี่เป็นหนึ่งในนั้น หากคุณอ้างถึงตัวแปรในลูปนี้สองครั้ง รายการค่าจะถือเป็นค่าเดียว หลายคนตกหลุมพรางนี้ ระวังและอย่ายกตัวแปรของคุณซ้ำในลูป for
$ cat for2-wrong.sh i=1 weekdays="Mon Tue Wed Thu Fri" for day in "$weekdays" do echo "Weekday $((i++)) : $day" done $ ./for2-wrong.sh Weekday 1 : Mon Tue Wed Thu Fri
3. อย่าระบุรายการ หาได้จากพารามิเตอร์ตำแหน่ง
หากคุณไม่ได้ระบุคีย์เวิร์ด "ใน" ตามด้วยรายการค่าใดๆ ใน bash for loop จะใช้พารามิเตอร์ตำแหน่ง (เช่น อาร์กิวเมนต์ที่ส่งผ่านไปยังเชลล์สคริปต์)
$ cat for3.sh i=1 for day do echo "Weekday $((i++)) : $day" done $ ./for3.sh Mon Tue Wed Thu Fri Weekday 1 : Mon Weekday 2 : Tue Weekday 3 : Wed Weekday 4 : Thu Weekday 5 : Fri
ข้อควรระวัง: โปรดใช้ความระมัดระวังหากคุณใช้วิธีนี้ คุณไม่ควรใส่คีย์เวิร์ด "ใน" ในลูป for หากคุณปล่อยคีย์เวิร์ด "ใน" โดยไม่มีค่าใดๆ คีย์เวิร์ดจะไม่ใช้พารามิเตอร์ตำแหน่งดังที่แสดงด้านล่าง มันจะไม่เข้าไปในวง เช่น for loop จะไม่ถูกดำเนินการดังแสดงในตัวอย่างด้านล่าง
$ cat for3-wrong.sh i=1 for day in do echo "Weekday $((i++)) : $day" done $ ./for3-wrong.sh Mon Tue Wed Thu Fri
หมายเหตุ :อ้างถึงบทความก่อนหน้าของเราเพื่อทำความเข้าใจเพิ่มเติมเกี่ยวกับพารามิเตอร์ตำแหน่ง bash
4. เอาต์พุตคำสั่ง Unix เป็นค่ารายการหลังคีย์เวิร์ด “in”
คุณสามารถใช้ผลลัพธ์ของคำสั่ง UNIX / Linux เป็นรายการค่าของลูป for โดยใส่คำสั่งในเครื่องหมายย้อนกลับ ` ` ดังที่แสดงด้านล่าง
$ cat for4.sh i=1 for username in `awk -F: '{print $1}' /etc/passwd` do echo "Username $((i++)) : $username" done $ ./for4.sh Username 1 : ramesh Username 2 : john Username 3 : preeti Username 4 : jason ..
5. วนรอบไฟล์และไดเร็กทอรีใน for loop
ในการวนรอบไฟล์และไดเร็กทอรีภายใต้ไดเร็กทอรีเฉพาะ เพียงแค่ cd ไปยังไดเร็กทอรีนั้น และให้ * ในลูป for ดังที่แสดงด้านล่าง
ตัวอย่างต่อไปนี้จะวนรอบไฟล์และไดเร็กทอรีทั้งหมดภายใต้โฮมไดเร็กตอรี่ของคุณ
$ cat for5.sh i=1 cd ~ for item in * do echo "Item $((i++)) : $item" done $ ./for5.sh Item 1 : positional-parameters.sh Item 2 : backup.sh Item 3 : emp-report.awk Item 4 : item-list.sed Item 5 : employee.db Item 8 : storage Item 9 : downloads
การใช้ * ใน bash for loop จะคล้ายกับไฟล์ globbing ที่เราใช้ในบรรทัดคำสั่ง linux เมื่อเราใช้คำสั่ง ls (และคำสั่งอื่นๆ)
ตัวอย่างเช่น ต่อไปนี้จะแสดงไฟล์และไดเร็กทอรีทั้งหมดภายใต้โฮมไดเร็กตอรี่ของคุณ นี่คือแนวคิดที่ใช้ในตัวอย่าง for5.sh ด้านบน
cd ~ ls *
ต่อไปนี้จะแสดงไฟล์ *.conf ทั้งหมดที่ขึ้นต้นด้วย a, b หรือ c หรือ d ภายใต้ไดเร็กทอรี /etc
$ ls -1 /etc/[abcd]*.conf /etc/asound.conf /etc/autofs_ldap_auth.conf /etc/cas.conf /etc/cgconfig.conf /etc/cgrules.conf /etc/dracut.conf
อาร์กิวเมนต์เดียวกันกับที่ใช้ในคำสั่ง ls ด้านบน สามารถใช้ใน bash for loop ดังที่แสดงในตัวอย่างด้านล่าง
$ cat for5-1.sh i=1 for file in /etc/[abcd]*.conf do echo "File $((i++)) : $file" done $ ./for5-1.sh File 1 : /etc/asound.conf File 2 : /etc/autofs_ldap_auth.conf File 3 : /etc/cas.conf File 4 : /etc/cgconfig.conf File 5 : /etc/cgrules.conf File 6 : /etc/dracut.conf
6. หลุดพ้นจากวง for loop
คุณสามารถแยก for loop โดยใช้คำสั่ง 'break' ดังที่แสดงด้านล่าง
$ cat for6.sh i=1 for day in Mon Tue Wed Thu Fri do echo "Weekday $((i++)) : $day" if [ $i -eq 3 ]; then break; fi done $ ./for6.sh Weekday 1 : Mon Weekday 2 : Tue
7. ต่อจากด้านบนสุดของ for loop
ภายใต้เงื่อนไขบางประการ คุณสามารถละเว้นคำสั่งที่เหลือใน for loop และวนซ้ำจากด้านบนอีกครั้ง (สำหรับค่าถัดไปในรายการ) โดยใช้คำสั่ง Continue ดังที่แสดงด้านล่าง
ตัวอย่างต่อไปนี้จะเพิ่ม “(WEEKEND)” ในวันเสาร์และอาทิตย์ และ “(วันธรรมดา)” ในวันที่เหลือ
$ cat for7.sh i=1 for day in Mon Tue Wed Thu Fri Sat Sun do echo -n "Day $((i++)) : $day" if [ $i -eq 7 -o $i -eq 8 ]; then echo " (WEEKEND)" continue; fi echo " (weekday)" done $ ./for7.sh Day 1 : Mon (weekday) Day 2 : Tue (weekday) Day 3 : Wed (weekday) Day 4 : Thu (weekday) Day 5 : Fri (weekday) Day 6 : Sat (WEEKEND) Day 7 : Sun (WEEKEND)
8. Bash for loop โดยใช้ไวยากรณ์โปรแกรม C
ตัวอย่างนี้ใช้วิธีที่ 2 ของ bash for loop ซึ่งคล้ายกับไวยากรณ์ C for loop ตัวอย่างต่อไปนี้สร้าง 5 หมายเลขสุ่มโดยใช้ bash C-style for loop
$ cat for8.sh for (( i=1; i <= 5; i++ )) do echo "Random number $i: $RANDOM" done $ ./for8.sh Random number 1: 23320 Random number 2: 5070 Random number 3: 15202 Random number 4: 23861 Random number 5: 23435
9. Infinite Bash for loop
เมื่อคุณไม่ได้ระบุการเริ่มต้น เงื่อนไข และการเพิ่มใน bash C-style for loop มันจะกลายเป็นวนซ้ำไม่สิ้นสุด คุณต้องกด Ctrl-C เพื่อหยุดการวนซ้ำ
$ cat for9.sh i=1; for (( ; ; )) do sleep $i echo "Number: $((i++))" done
อย่างที่เราได้กล่าวไว้ข้างต้น ให้กด Ctrl-C เพื่อแยก bash นี้ออกไม่สิ้นสุดสำหรับตัวอย่างลูป
$ ./for9.sh Number: 1 Number: 2 Number: 3
10. การใช้เครื่องหมายจุลภาคใน bash C-style for loop
ใน bash c-style loop นอกเหนือจากการเพิ่มค่าที่ใช้ในเงื่อนไขแล้ว คุณยังสามารถเพิ่มค่าอื่นๆ ตามที่แสดงด้านล่างได้
ในส่วนเริ่มต้นและส่วนเพิ่มของ bash C-style for loop คุณสามารถมีค่าได้หลายค่าโดยคั่นด้วยเครื่องหมายจุลภาคดังที่แสดงด้านล่าง
ต่อไปนี้สำหรับลูปดำเนินการทั้งหมด 5 ครั้งโดยใช้ตัวแปร i อย่างไรก็ตาม ตัวแปร j เริ่มต้นด้วย 5 และเพิ่มขึ้น 5 ทุกครั้งที่มีการดำเนินการวนซ้ำ
$ cat for10.sh for ((i=1, j=10; i <= 5 ; i++, j=j+5)) do echo "Number $i: $j" done $ ./for10.sh Number 1: 10 Number 2: 15 Number 3: 20 Number 4: 25 Number 5: 30
11. ช่วงของตัวเลขหลังคีย์เวิร์ด “ใน”
คุณสามารถวนซ้ำโดยใช้ช่วงของตัวเลขใน for loop “in” โดยใช้การขยายวงเล็บปีกกา
ตัวอย่างต่อไปนี้วนซ้ำ 10 ครั้งโดยใช้ค่า 1 ถึง 10
$ cat for11.sh for num in {1..10} do echo "Number: $num" done $ ./for11.sh Number: 1 Number: 2 Number: 3 Number: 4 Number: 5 ...
12. ช่วงของตัวเลขที่มีการเพิ่มขึ้นหลังจากคีย์เวิร์ด “ใน”
ตัวอย่างต่อไปนี้วนซ้ำ 5 ครั้งโดยใช้ค่า 1 ถึง 10 โดยเพิ่มขึ้นทีละ 2 นั่นคือเริ่มต้นด้วย 1 และเพิ่มขึ้นเรื่อย ๆ 2 จนกว่าจะถึง 10
$ cat for12.sh for num in {1..10..2} do echo "Number: $num" done $ ./for12.sh Number: 1 Number: 3 Number: 5 Number: 7 Number: 9
ปล: อย่าลืมบุ๊กมาร์กบทความนี้ไว้ใช้อ้างอิงในอนาคต