Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Lập Trình Bash

Thành Thạo Vòng Lặp For Bash: 12 Ví Dụ Cần Thiết Cho Script Shell Linux

Thành Thạo Vòng Lặp For Bash: 12 Ví Dụ Cần Thiết Cho Script Shell LinuxCó hai loại vòng lặp for bash. Một dùng từ khóa "in" với danh sách giá trị, loại hai dùng cú pháp giống lập trình C.

Bài viết này là phần của series hướng dẫn bash đang tiếp diễn.

Giải thích cả hai phương pháp vòng lặp for bash, và cung cấp 12 ví dụ khác nhau cách dùng vòng lặp for bash trong script shell.

Đánh dấu bài này để tham khảo sau, vì đây là bài duy nhất bạn cần tham khảo về cách dùng vòng lặp for bash với ví dụ.

Phương pháp 1: Vòng Lặp For Bash Dùng "in" Và Danh Sách Giá Trị

Cú pháp:

for varname in list do command1 command2 .. done

Trong cú pháp trên:

  • for, in, do và done là từ khóa
  • "list" chứa danh sách giá trị. Danh sách có thể là biến chứa vài từ tách bằng khoảng trắng. Nếu list bị thiếu trong câu lệnh for, nó lấy tham số vị trí (positional parameter) được truyền vào shell.
  • varname là bất kỳ tên biến Bash nào.

Trong dạng này, câu lệnh for thực thi các lệnh trong thân vòng lặp, một lần cho mỗi mục trong list. Ví dụ, nếu list chứa 5 mục, vòng lặp for sẽ chạy tổng cộng 5 lần, một lần cho mỗi mục. Mục hiện tại từ list sẽ được lưu trong biến "varname" mỗi lần lặp. "varname" này có thể xử lý trong thân vòng lặp for.

Phương pháp 2: Vòng Lặp For Bash Dùng Cú Pháp Giống C

Dạng thứ hai của vòng lặp for giống vòng lặp for trong ngôn ngữ lập trình "C", có ba biểu thức (khởi tạo, điều kiện và cập nhật).

for (( expr1; expr2; expr3 )) do command1 command2 .. done

Trong cú pháp lệnh for bash trên,

  • Trước lần lặp đầu, expr1 được đánh giá. Thường dùng để khởi tạo biến cho vòng lặp.
  • Tất cả câu lệnh giữa do và done được thực thi lặp lại cho đến khi giá trị expr2 là TRUE.
  • Sau mỗi lần lặp, expr3 được đánh giá. Thường dùng để tăng biến đếm vòng lặp.

12 ví dụ sau chỉ cách dùng vòng lặp for bash theo nhiều cách khác nhau.

1. Giá trị tĩnh cho list sau từ khóa "in"

Trong ví dụ sau, danh sách giá trị (Mon, Tue, Wed, Thu, Fri) được đưa trực tiếp sau từ khóa "in" trong vòng lặp for bash.

$ 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

Cảnh báo: Danh sách giá trị không được tách bằng dấu phẩy (Mon, Tue, Wed, Thu, Fri). Dấu phẩy sẽ được xem như một phần của giá trị. Tức là thay vì "Mon", nó sẽ dùng "Mon," như giá trị như ví dụ dưới.

$ 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

Cảnh báo: Danh sách giá trị không được bao trong ngoặc kép. ("Mon Tue Wed Thu Fri"). Nếu bao trong ngoặc kép, nó sẽ được xem như một giá trị đơn lẻ (thay vì 5 giá trị khác nhau), như ví dụ dưới.

$ 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. Biến cho list sau từ khóa "in"

Thay vì đưa giá trị trực tiếp trong vòng lặp for, bạn có thể lưu giá trị trong biến, và dùng biến trong vòng lặp for sau "in", như ví dụ sau.

$ 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

Cảnh báo: Như thực hành tốt, bạn nên luôn đặt biến bash trong ngoặc kép khi tham chiếu. Có vài ngoại lệ cho quy tắc này. Đây là một trong số đó. Nếu bạn đặt biến trong ngoặc kép kép trong vòng lặp for này, danh sách giá trị sẽ được xem như một giá trị đơn. Nhiều người rơi vào cái bẫy này. Cẩn thận và không đặt biến trong ngoặc kép kép trong vòng lặp 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. Không chỉ định list; lấy từ tham số vị trí

Nếu bạn không chỉ định từ khóa "in" theo sau bất kỳ danh sách giá trị nào trong vòng lặp for bash, nó sẽ dùng tham số vị trí (tức là đối số truyền cho script shell).

$ 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

Cảnh báo: Hãy cẩn thận nếu dùng phương pháp này. Bạn không nên bao gồm từ khóa "in" trong vòng lặp for. Nếu bạn để từ khóa "in" không có giá trị, nó sẽ không dùng tham số vị trí như dưới. Nó sẽ không vào vòng lặp. Tức là vòng lặp for không bao giờ được thực thi như ví dụ dưới.

$ cat for3-wrong.sh i=1 for day in do echo "Weekday $((i++)) : $day" done $ ./for3-wrong.sh Mon Tue Wed Thu Fri

Lưu ý: Tham khảo bài trước để hiểu thêm về tham số vị trí bash.

4. Đầu ra lệnh Unix làm giá trị list sau "in"

Bạn có thể dùng đầu ra bất kỳ lệnh UNIX/Linux nào làm danh sách giá trị cho vòng lặp for bằng cách đặt lệnh trong back-ticks ` ` như dưới.

$ 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. Lặp qua file và thư mục trong vòng lặp for

Để lặp qua file và thư mục dưới thư mục cụ thể, chỉ cần cd đến thư mục đó, và đưa * trong vòng lặp for như sau.

Ví dụ sau sẽ lặp qua tất cả file và thư mục dưới thư mục home của bạn.

$ 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

Việc dùng * trong vòng lặp for bash tương tự file globbing dùng trong dòng lệnh linux khi dùng ls (và lệnh khác).

Ví dụ, sau sẽ hiển thị tất cả file và thư mục dưới thư mục home. Đây là khái niệm dùng trong ví dụ for5.sh trên.

cd ~ ls *

Sau sẽ hiển thị tất cả file *.conf bắt đầu bằng a, b, c, hoặc d dưới /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

Cùng đối số dùng trong lệnh ls trên, có thể dùng trong vòng lặp for bash, như ví dụ dưới.

$ 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. Thoát khỏi vòng lặp for

Bạn có thể thoát khỏi vòng lặp for dùng lệnh 'break' như sau.

$ 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. Tiếp tục từ đầu vòng lặp for

Dưới điều kiện nhất định, bạn có thể bỏ qua phần còn lại của lệnh trong vòng lặp for, và tiếp tục vòng lặp từ đầu lại (cho giá trị tiếp theo trong list), dùng lệnh continue như sau.

Ví dụ sau thêm "(WEEKEND)" cho Sat và Sun, và "(weekday)" cho các ngày còn lại.

$ 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. Vòng lặp for bash dùng cú pháp chương trình C

Ví dụ này dùng phương pháp 2 của vòng lặp for bash, giống cú pháp for C. Ví dụ sau tạo 5 số ngẫu nhiên dùng vòng lặp for kiểu C bash.

$ 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. Vòng lặp for bash vô hạn

Khi bạn không cung cấp khởi tạo, điều kiện, và tăng trong vòng lặp for kiểu C bash, nó sẽ thành vòng lặp vô hạn. Bạn cần nhấn Ctrl-C để dừng.

$ cat for9.sh i=1; for (( ; ; )) do sleep $i echo "Number: $((i++))" done

Như nói trên, nhấn Ctrl-C để thoát ví dụ vòng lặp for vô hạn bash này.

$ ./for9.sh Number: 1 Number: 2 Number: 3

10. Dùng dấu phẩy trong vòng lặp for kiểu C bash

Trong vòng lặp kiểu C bash, ngoài tăng giá trị dùng trong điều kiện, bạn cũng có thể tăng giá trị khác như sau.

Trong phần khởi tạo, và phần tăng của vòng lặp for kiểu C bash, bạn có thể có nhiều giá trị tách bằng dấu phẩy như sau.

Vòng lặp for sau chạy tổng 5 lần, dùng biến i. Tuy nhiên biến j bắt đầu từ 5, và tăng 5 mỗi lần vòng lặp chạy.

$ 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. Phạm vi số sau từ khóa "in"

Bạn có thể lặp qua phạm vi số trong for "in" dùng brace expansion (mở rộng ngoặc nhọn).

Ví dụ sau lặp 10 lần dùng giá trị 1 đến 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. Phạm vi số với bước nhảy sau "in"

Ví dụ sau lặp 5 lần dùng giá trị 1 đến 10, với bước nhảy 2. Tức là bắt đầu từ 1, tăng 2 mỗi lần, cho đến 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

PS: Đừng quên đánh dấu bài này để tham khảo sau.