Các cấu trúc điều khiển, xử lý chuỗi đơn giản và Dictionaries trong Bash

Cũng như các ngôn ngữ lập trình khác, Bash cũng có các cấu trúc điều khiển như rẽ nhánh, lặp…để có thể điều khiển code theo hướng mong muốn của chúng ta. Trong bài viết này, chúng ta hãy cùng nhau tìm hiểu về các cấu trúc điều khiển này nhé. Ngoài ra, trong bài viết này, chúng ta sẽ nói đến 1 kiểu dữ liệu mà nếu các bạn đã từng sử dụng hay tương tác với python sẽ thấy được tác dụng tuyệt vời của nó, đó chính là “Dictionaries”.

Các cấu trúc điều khiển:

  1. Rẽ nhánh:
    • If

    Cấu trúc:

    if [condition];
    then
       commands;
    fi

    với [condition] ở đây là các cấu trúc so sánh đã được giới thiệu ở bài trước. “commands” là code thực thi mà ta muốn khi thoả mảng điều kiện [condition] ở trên.

    Ví dụ:

    if (( $a < $b ));
    then
       echo "$a is smaller than $b"
    fi
    
    if [[ -e "file.txt" ]];
    then
       echo "file exists"
    fi
    • if – else, if – else if – else

    Cấu trúc:

    if [condition];
    then
         commands_01;
    else
        commands_02;
    fi
    
    if [condition];
    then
        commands;
    elif [condition];
    then
        commands;
    else
        commands;
    fi

    Ví dụ:

    if [[ $a -lt 10 ]];
    then
      echo "a < 10"
    elif [[ $a -gt 20 ]];
    then
      echo "a > 20"
    else
      echo "a < 20 and a > 10"
    fi

    Ngoài ra, ta còn có thể viết dưới dạng sau:

    # thực hiện nếu điều kiện condition là đúng (TRUE).
    [ condition ] && action
    
    # thực hiện nếu điều kiện condition là sai (FALSE).
    [ condition ] || action
    • case … esac

    Cấu trúc:

    case “$luachon” in
       giatrimau_1) Các câu lệnh ;;
       giatrimau_2) Các câu lệnh ;;
       giatrimau_n) Các câu lệnh ;;
       *) Câu lệnh cho TH còn lại ;; (Giống default trong C/C++)
    esac

    Ví dụ:

    case "$1" in
      1) echo 'Monday' ;;
      2) echo 'Tuesday' ;;
      3) echo 'Wednesday' ;;
      4) echo 'Thursday' ;;
      5) echo 'Friday' ;;
      6) echo 'Saturday' ;;
      7) echo 'Sunday' ;;
      *)
    
      echo "Don't match anything"
      exit 1
    
    ;;
    esac
    
    
    
    case "$1" in
      start | up)
        vagrant up
        ;;
    
      *)
        echo "Usage: $0 {start|stop|ssh}"
        ;;
    esac

     

  2. Vòng lập:
  • for: hoạt động dựa trên danh sách của các mục. Nó lập đi lập lại một tập các câu lệnh cho mỗi mục có trong danh sách. Có thể sử duyệt mảng với điều kiện cho trước (khá giống với trong C/C++)
    • Vòng lặp cơ bản:
for i in /etc/rc.*; do
  echo $i
done


for i in Mon Tue Wed Thurs Fri Sat Sun
do
  echo $i
done
    • Vòng lặp kiểu ngôn ngữ C (C-like)
for ((i = 0 ; i < 100 ; i++));
do
  echo $i
done

for (( i=0; $i < $elements; i++ ));
do
  echo ${array[$i]}
done
    • Vòng lặp khoảng số:
for i in {1..5}; do
    echo "Welcome $i"
done

# lặp từ 5 -> 50 với mỗi step nhảy có giá trị 5 đơn vị.
for i in {5..50..5}; do
    echo "Welcome $i"
done
  • while: chủ yếu sử dụng vòng lặp này khi ta muốn thực thi một tập lệnh lặp đi lặp lại nhiều lần trong khi điều kiện vẫn còn đúng. (Ở phần điều kiện nếu là true thì vòng lặp while sẽ được thực thi)
    • Vòng while cơ bản:
a=0
while [ $a –le 5 ]
do
  echo $a
  a=$(($a + 1))
done
    • Vòng while dùng để đọc file:
< file.txt | while read line;
do
  echo $line
done
  • until: ngược lại với while, vòng lặp này sẽ thực thi tập lệnh của nó khi giá trị điều kiện là sai. Nó sẽ chạy tới khi thỏa mãn điều kiện là đúng.
a=0
until [ ! $a –le 5 ]
do
  echo $a
  a=$(($a + 1))
done
  • select: vòng lặp cung cấp một danh sách menu từ một tập các phần tử được cho có đánh số ở đầu để lựa chọn. (Đây là vòng lặp có sẵn trong ksh được điều chỉnh vào bash. Nó không có sẵn trong bash
#!/bin/bash

select brand in Samsung Sony iphone symphony Walton
do
echo "You have chosen $brand"
done


select DRINK in tea cofee water juice appe all none
do
   case $DRINK in
     tea|cofee|water|all)
        echo "Go to canteen"
        ;;
     juice|appe)
        echo "Available at home"
        ;;
     none)
        break
        ;;
     *) echo "ERROR: Invalid selection"
        ;;
  esac
done

Các cách xử lý chuỗi đơn giản:

  • Xoá chuỗi con trước chuỗi
    • “#” : loại bỏ phần ngắn nhất ứng với $substring ở phía trước chuỗi $string.
    • “##” : loại bỏ phần dài nhất ứng với $substring ở phía trước chuỗi $string.

Ví dụ: Ta có chuỗi sau string=”this is a name this is a substring test”

substring1=${string#t*i}
substring2=${string##t*i}

Sau khi chạy lệnh trên ta sẽ được kết quả như sau:

echo $substring1   # s is a name this is a substring test

echo $substring2​   # ng test

  • Xoá chuỗi con sau chuỗi
    • “%” : loại bỏ phần ngắn nhất ứng với $substring ở phía sau chuỗi $string.
    • “%%” : loại bỏ phần dài nhất ứng với $substring ở phía sau chuỗi $string.

Ví dụ: ta có chuỗi sau string=”this is a name this is a substring test”

substring1=${string%n*t}
substring2=${string%%n*t}

Sau khi chạy lệnh trên ta sẽ được kết quả như sau:

echo $substring1   # this is a name this is a substri
echo $substring2​   # this is a

  • Thay thế chuỗi

Cấu Trúc:

# thay thế chuỗi con đầu tiên tìm thấy được
${string/[substring]/[replacement]}

# thay thế tất cả chuỗi con tìm thấy được
${string//[substring]/[replacement]}

Ví dụ:

string = “this is a name this is a substring test”

# thay thế chuỗi "this is a" đầu tiên tìm thấy được bằng "demo"
# kết quả: demo name this is a substring test
echo ${string/this is a/demo}

# thay thế tất cả chuỗi "this is a" tìm thấy được bằng "demo"
# kết quả: demo name demo substring test
echo ${string//this is a/demo}

Cấu trúc:

# Nếu $substring ở phía đầu chuỗi $string thì thay thế $subtring thành $replacement.
${string/#substring/replacement}

# Nếu $substring ở phía cuối chuỗi $string thì thay thế $subtring thành $replacement.
${string/%substring/replacement}​

Ví dụ:

string = “this is a name  substring test this is a”

echo ${string/#this is a/demo} # kq: demo name this is a substring test
echo ${string/%this is a/demo} # kq: this is a name substring test demo​
  • Độ dài chuỗi

Cấu Trúc:

${#string}​

Ví dụ:

string="this is a name this is a substring test"

echo ${#string}     # kq: 39​
  • Lấy ra xâu con của chuỗi bắt đầu tại vị trí i

Cấu Trúc:

${string:position:length}

Ví dụ:

string="this is a name this is a substring test"

echo ${string:8:15}    # kq: a name this is​
  • Viết thường ký tự đầu tiên của chuỗi
STR="HELLO WORLD!"

echo ${STR,}   # kq: hELLO WORLD!​
  • Viết thường tất cả ký tự của chuỗi:
STR="HELLO WORLD!"

echo ${STR,,}  # kq: hello world!​
  • Viết hoa ký tự đầu tiên của chuỗi:
STR="hello world!"

echo ${STR^}   # kq: Hello world! ​
  • Viết hoa tất cả ký tự của chuỗi:
STR="hello world!"

echo ${STR^^}  # kq: HELLO WORLD!​

Dictionaries:

Dictionaries (Dictionary object) có thể được xem là 1 mảng kết hợp với cấu trúc “key” => “value” là một phần tử của mảng.

  • Khai báo:
declare -A sounds​
  • Gán giá trị:
sounds[dog]="bark"
sounds[cow]="moo"
sounds[bird]="tweet"
sounds[wolf]="howl"
  • Lấy giá trị của key “dog”
echo ${sounds[dog]}  # kq: bark​
  • Lấy tất cả giá trị của “sounds”
echo ${sounds[@]}   # kq: bark howl moo tweet​
  • Lấy tất cả các key của “sounds”
echo ${!sounds[@]}   # kq: dog wolf cow bird​
  • Lấy số lượng phần tử có trong “sounds”
echo ${#sounds[@]}    # kq: 4​
  • Xoá 1 phần tử có “key” trong “sounds”
unset sounds[dog]

echo ${sounds[@]}   # kq: howl moo tweet​ ​
echo ${!sounds[@]}   # kq: wolf cow bird​
  • Lặp với Dictionaries
# in ra tất cả giá trị của sounds
for val in "${sounds[@]}"; do
  echo $val
done

# in ra tất cả key của sounds
for key in "${!sounds[@]}"; do
  echo $key
done​

Qua bài này, chúng ta đã có thể nắm được các cấu trúc điều khiển của bash, từ đó ta có thể viết được chương trình theo như mong muốn của chúng ta một cách dễ dàng. Hãy thật quen thuộc với các cấu trúc điều khiển này nhé, vì hầu như có thể nói, nếu ta nắm vững và sử dụng được các cấu trúc điều khiển này có thể giúp cho chương trình của chúng ta thực hiện hầu như tất cả mọi thứ mà chúng ta mong muốn đó. Ngoài ra, ta đã làm quen được với một kiểu dữ liệu mới là Dictionaries, với kiểu dữ liệu này, ta có thể tuỳ biến cách lưu trữ dữ liệu tạm của chúng ta 1 cách linh hoạt hơn, giúp ích cho chúng ta rất lớn trong việc xử lý vòng lặp và truy xuất gía trị mong muốn. 

Các toán tử cơ bản, cấu trúc so sánh và mảng trong Bash

Shell là gì ? Sự khác nhau giữa SH và Bash

Hướng dẫn thực hiện cấu hình chuyển hướng toàn bộ truy cập tên miền bằng file .htaccess

Hướng dẫn bảo vệ wp-admin|wp-login.php tránh bị tấn công dò mật khẩu (brute-force) cho website WordPress

Cài đặt WordPress trên hosting tại 7Host chỉ với 1 click.

Tối ưu MySQL bằng Query Caching

Hướng Dẫn Cài Đặt Plugin WP Mail SMTP Để Gửi Mail Trên WordPress (SMTP Mail WordPress)

Hướng dẫn cài đặt WordPress trên DirectAdmin