ทุกสิ่งที่คุณจำเป็นต้องรู้เกี่ยวกับ Bash For Loops ใน Linux

ทุกสิ่งที่คุณจำเป็นต้องรู้เกี่ยวกับ Bash For Loops ใน Linux

สคริปต์ทุบตีเป็นวิธีที่มีประสิทธิภาพสูงในการทำงานอัตโนมัติ โดยเฉพาะอย่างยิ่งผู้ที่ใช้ประโยชน์จากโปรแกรมอื่นที่มีอยู่ ระบบอัตโนมัตินี้มักจะต้องทำซ้ำการดำเนินการที่คล้ายกันหลายครั้ง ซึ่งเป็นที่ที่ สำหรับวง มาเป็นของตัวเอง





ผู้ดูแลระบบ Linux และ Mac มักจะคุ้นเคยกับการเขียนสคริปต์ผ่านเทอร์มินัล แต่แม้แต่ผู้ใช้ Windows ก็สามารถทำได้ ลงมือดำเนินการกับระบบย่อย Windows สำหรับ Linux .





สคริปต์ทุบตีทำงานอย่างไร

สคริปต์ทุบตีเป็นเพียงไฟล์ข้อความธรรมดาที่มีชุดคำสั่งที่เชลล์ทุบตีสามารถอ่านและดำเนินการได้ Bash เป็นเชลล์เริ่มต้นใน macOS ก่อน Catalina และลีนุกซ์ส่วนใหญ่





หากคุณไม่เคยทำงานกับเชลล์สคริปต์มาก่อน คุณควรเริ่มด้วยกรณีที่ง่ายที่สุด สิ่งนี้จะช่วยให้คุณฝึกฝนแนวคิดหลักรวมถึงการสร้างสคริปต์และการดำเนินการ

ขั้นแรก สร้างไฟล์ต่อไปนี้ในตำแหน่งที่สะดวก (ควรเปิดเทอร์มินัลแล้วไปที่ไดเร็กทอรีที่ต้องการก่อน):



#!/bin/bash
echo 'Hello, World'

บรรทัดแรกบอกสิ่งที่รันโปรแกรมนี้ว่าจะรันอย่างไร (เช่นใช้ bash interpreter) คำสั่งที่สองเป็นเพียงคำสั่งที่เหมือนกับคำสั่งอื่นๆ ที่คุณอาจป้อนบนบรรทัดคำสั่ง บันทึกไฟล์นั้นเป็น สวัสดี_world.sh , แล้ว:

$ chmod +x hello_world.sh
$ ./hello_world.sh

NS chmod คำสั่งในบรรทัดแรกทำให้ไฟล์เรียกทำงานได้ หมายความว่าสามารถเรียกใช้ได้โดยพิมพ์ชื่อ เช่นเดียวกับในบรรทัดที่สอง





หากคุณเห็นคำว่า Hello World ปรากฏขึ้นบนบรรทัดในเทอร์มินัลของคุณ แสดงว่าทุกอย่างทำงานตามที่ต้องการ

วิธีการทำงานของลูป

โดยทั่วไป โปรแกรม for loop มีอยู่สองประเภทหลัก: ตัวเลข และ แต่ละ . โดยทั่วไปแล้วประเภทตัวเลขเป็นประเภททั่วไป แต่ในการใช้งาน bash มักจะตรงกันข้าม





ตัวเลขสำหรับลูปมักจะเน้นที่จำนวนเต็มเดียว ซึ่งกำหนดจำนวนการวนซ้ำที่จะดำเนินการ เช่น

for (i = 0; i <100; i++) {
/* statements to execute repeatedly */
}

นี่คือลูปที่คุ้นเคยซึ่งจะวนซ้ำ 100 ครั้ง เว้นแต่ว่า i จะถูกแก้ไขภายในลูป หรือคำสั่งอื่นทำให้การดำเนินการของลูป for หยุดทำงาน

ในทางตรงกันข้าม Foreach loops มักจะทำงานกับโครงสร้าง เช่น รายการหรืออาร์เรย์ และวนซ้ำทุกรายการภายในคอลเลกชันนั้น:

people = [ 'Peter', 'Paul', 'Mary' ]
foreach (people as person) {
if (person == 'Paul') {
...
}
}

บางภาษาใช้ไวยากรณ์ที่แตกต่างกันเล็กน้อย ซึ่งจะสลับลำดับของคอลเลกชันและรายการ:

people = [ 'Peter', 'Paul', 'Mary' ]
for (person in people) {
if (person == 'Paul') {
...
}
}

สำหรับในลูป

ในทุบตี foreach—หรือ สำหรับใน —loop เป็นเรื่องปกติมากขึ้น ไวยากรณ์พื้นฐานคือง่ายๆ:

for arg in [list]
do
/* statements to execute repeatedly */
/* the value of arg can be obtained using $arg */
done

ตัวอย่างเช่น ในการวนซ้ำไฟล์ที่มีชื่อชัดเจนสามไฟล์:

windows 10 ต้องการพื้นที่เท่าใด
for file in one.c two.c three.c
do
ls '$file'
done

หากไฟล์ดังกล่าวมีอยู่ในไดเร็กทอรีปัจจุบัน เอาต์พุตจากสคริปต์นี้จะเป็น:

one.c
two.c
three.c

แทนที่จะได้รับชุดไฟล์ตายตัว สามารถรับรายการผ่านรูปแบบ glob (หนึ่งรวมถึงสัญลักษณ์แทน - อักขระพิเศษที่แสดงถึงอักขระอื่น ๆ) ในตัวอย่างต่อไปนี้ for loop จะวนซ้ำในไฟล์ทั้งหมด (ในไดเร็กทอรีปัจจุบัน) ที่มีชื่อลงท้ายด้วย '.xml':

for file in *.xml
do
ls -l '$file'
done

นี่คือตัวอย่างผลลัพธ์บางส่วน:

$ -rw-r--r-- 1 bobby staff 2436 3 Nov 2019 feed.xml
$ -rw-r--r-- 1 bobby staff 6447 27 Oct 16:24 sitemap.xml

วิธีนี้อาจดูเหมือนใช้เวลานานมาก:

$ ls -l *.xml

แต่มีข้อแตกต่างที่สำคัญคือ for loop ดำเนินการ ลส โปรแกรม 2 ครั้งแยกกันโดยส่งชื่อไฟล์เดียวในแต่ละครั้ง ในตัวอย่าง ls ที่แยกจากกัน รูปแบบ glob (*.xml) จะจับคู่ชื่อไฟล์ก่อน จากนั้นจึงส่งทั้งหมดเป็นพารามิเตอร์บรรทัดคำสั่งแต่ละรายการ ไปยังอินสแตนซ์เดียวของ ลส .

นี่คือตัวอย่างที่ใช้ ห้องน้ำ (จำนวนคำ) โปรแกรมสร้างความแตกต่างให้ชัดเจนยิ่งขึ้น:

$ wc -l *.xml
44 feed.xml
231 sitemap.xml
275 total

NS ห้องน้ำ โปรแกรมจะนับจำนวนบรรทัดในแต่ละไฟล์แยกกัน จากนั้นจะพิมพ์จำนวนบรรทัดทั้งหมดออกมาทั้งหมด ในทางตรงกันข้าม if ห้องน้ำ ทำงานภายใน for loop:

for file in *.xml
do
wc -l $file
done

คุณจะยังคงเห็นจำนวนของแต่ละไฟล์:

44 feed.xml
231 sitemap.xml

แต่ไม่มียอดสรุปโดยรวมเพราะ ห้องน้ำ ทำงานแบบแยกส่วน ทุกครั้งที่วนซ้ำวนซ้ำ

เมื่อรายการไม่ใช่รายการ

มีข้อผิดพลาดที่ง่ายมากและเกิดขึ้นบ่อยเมื่อต้องจัดการกับลูป เนื่องจากวิธีที่ bash จัดการกับอาร์กิวเมนต์/สตริงที่ยกมา การวนรอบรายการไฟล์ควรทำดังนี้:

for file in one.c two.c

ไม่เหมือนนี่:

for file in 'one.c two.c'

ตัวอย่างที่สองล้อมรอบชื่อไฟล์ด้วยเครื่องหมายคำพูดคู่ซึ่งส่งผลให้รายการมีพารามิเตอร์เพียงตัวเดียว for loop จะดำเนินการเพียงครั้งเดียว ปัญหานี้สามารถหลีกเลี่ยงได้โดยใช้ตัวแปรในกรณีดังกล่าว:

FILES='one.c two.c'
for file in $FILES
do
...
done

โปรดทราบว่าการประกาศตัวแปรเองจำเป็นต้องใส่ค่าในเครื่องหมายคำพูดคู่!

กาแล็กซี่นาฬิกา 3 กับแอคทีฟ2

สำหรับไม่มีรายการ

โดยไม่มีอะไรต้องทำซ้ำ for loop จะดำเนินการกับอาร์กิวเมนต์บรรทัดคำสั่งใดๆ ก็ตามที่มีให้กับสคริปต์เมื่อถูกเรียกใช้ ตัวอย่างเช่น หากคุณมีสคริปต์ชื่อ args.sh ประกอบด้วยสิ่งต่อไปนี้:

#!/bin/sh
for a
do
echo $a
done

จากนั้นการดำเนินการ args.sh จะให้สิ่งต่อไปนี้แก่คุณ:

$ ./args.sh one two three
one
two
three

Bash ตระหนักถึงกรณีนี้และปฏิบัติต่อ เพื่อทำ เทียบเท่ากับ สำหรับ $@ do โดยที่ $@ เป็นตัวแปรพิเศษที่แสดงถึงอาร์กิวเมนต์บรรทัดคำสั่ง

การจำลองตัวเลขแบบดั้งเดิมสำหรับลูป

สคริปต์ทุบตีมักจะจัดการกับรายการไฟล์หรือบรรทัดของเอาต์พุตจากคำสั่งอื่น ดังนั้น for in ประเภทของลูปจึงเป็นเรื่องปกติ อย่างไรก็ตาม ยังคงรองรับการทำงานแบบ c แบบดั้งเดิม:

for (( i=1; i<=5; i++ ))
do
echo $i
done

นี่คือรูปแบบคลาสสิกที่มีสามส่วนซึ่ง:

  1. ตัวแปรเริ่มต้น (i=1) เมื่อพบลูปครั้งแรก
  2. วนซ้ำต่อเนื่องตราบเท่าที่เงื่อนไข (i<=5) is true
  3. ทุกครั้งที่วนรอบ ตัวแปรจะเพิ่มขึ้น (i++)

การวนซ้ำระหว่างสองค่าเป็นข้อกำหนดทั่วไปเพียงพอที่มีทางเลือกที่สั้นกว่าและสับสนน้อยกว่าเล็กน้อย:

for i in {1..5}
do
echo $i
done

การขยายวงเล็บปีกกาที่เกิดขึ้นอย่างมีประสิทธิภาพแปลการวนซ้ำด้านบนเป็น:

for i in 1 2 3 4

การควบคุมลูปที่ละเอียดยิ่งขึ้นด้วยการหยุดและดำเนินการต่อ

ที่ซับซ้อนมากขึ้นสำหรับลูปมักจะต้องการวิธีการออกก่อนเวลาหรือเริ่มต้นลูปหลักใหม่ทันทีโดยมีค่าถัดไปในทางกลับกัน ในการทำเช่นนั้น bash ยืมคำสั่ง break และ continue ที่ใช้กันทั่วไปในภาษาโปรแกรมอื่นๆ ต่อไปนี้คือตัวอย่างที่ใช้ทั้งคู่เพื่อค้นหาไฟล์แรกที่มีความยาวมากกว่า 100 อักขระ:

#!/bin/bash
for file in *
do
if [ ! -f '$file' ]
then
echo '$file is not a file'
continue
fi
num_chars=$(wc -c <'$file')
echo $file is '$num_chars characters long'
if [ $num_chars -gt 100 ]
then
echo 'Found $file'
break
fi
done

for loop ที่นี่ทำงานกับไฟล์ทั้งหมดในไดเร็กทอรีปัจจุบัน หากไฟล์นั้นไม่ใช่ไฟล์ปกติ (เช่น หากเป็นไดเร็กทอรี) คำสั่ง Continue จะใช้เพื่อรีสตาร์ทลูปด้วยไฟล์ถัดไปตามลำดับ หากเป็นไฟล์ปกติ บล็อกแบบมีเงื่อนไขที่สองจะกำหนดว่าไฟล์นั้นมีอักขระมากกว่า 100 ตัวหรือไม่ ถ้าเป็นเช่นนั้น คำสั่ง break จะใช้เพื่อออกจากลูป for ทันที (และไปถึงจุดสิ้นสุดของสคริปต์)

บทสรุป

สคริปต์ทุบตีเป็นไฟล์ที่มีชุดคำสั่งที่สามารถดำเนินการได้ การวนซ้ำช่วยให้ส่วนของสคริปต์สามารถทำซ้ำได้หลายครั้ง ด้วยการใช้ตัวแปร คำสั่งภายนอก และคำสั่ง break and continue สคริปต์ทุบตีสามารถใช้ตรรกะที่ซับซ้อนมากขึ้น และทำงานที่หลากหลาย

แบ่งปัน แบ่งปัน ทวีต อีเมล การอัพเกรดเป็น Windows 11 คุ้มค่าหรือไม่?

Windows ได้รับการออกแบบใหม่ แต่นั่นเพียงพอที่จะโน้มน้าวให้คุณเปลี่ยนจาก Windows 10 เป็น Windows 11 หรือไม่

อ่านต่อไป
หัวข้อที่เกี่ยวข้อง
  • การเขียนโปรแกรม
  • ลินุกซ์
เกี่ยวกับผู้เขียน Bobby Jack(58 บทความเผยแพร่)

Bobby เป็นผู้ที่ชื่นชอบเทคโนโลยีซึ่งทำงานเป็นนักพัฒนาซอฟต์แวร์มาเกือบสองทศวรรษ เขาหลงใหลในการเล่นเกม ทำงานเป็นบรรณาธิการบทวิจารณ์ที่ Switch Player Magazine และหมกมุ่นอยู่กับทุกแง่มุมของการเผยแพร่ออนไลน์และการพัฒนาเว็บ

เพิ่มเติมจาก Bobby Jack

สมัครรับจดหมายข่าวของเรา

เข้าร่วมจดหมายข่าวของเราสำหรับเคล็ดลับทางเทคนิค บทวิจารณ์ eBook ฟรี และดีลพิเศษ!

คลิกที่นี่เพื่อสมัครสมาชิก