Tối ưu hóa Bash Script với Mảng và Mảng Kết hợp

Mảng là cấu trúc dữ liệu nền tảng trong Bash, cho phép lưu trữ và thao tác nhiều giá trị dưới một tên biến. Việc sử dụng mảng hiệu quả giúp đơn giản hóa logic xử lý dữ liệu, tăng tính rõ ràng và bảo trì mã nguồn—đặc biệt hữu ích trong quản trị hệ thống, tự động hóa tác vụ và xử lý đầu vào phức tạp.

Khởi tạo mảng

Bash hỗ trợ khởi tạo mảng theo cú pháp cơ bản:

inventory=("lửa" "băng" "sấm")

Để tường minh hơn về kiểu dữ liệu, nên dùng declare -a:

declare -a inventory=("lửa" "băng" "sấm")

Với mảng lớn, viết trên nhiều dòng giúp dễ đọc:

inventory=(
    "lửa"
    "băng"
    "sấm"
)

Truy cập phần tử

Truy cập phần tử qua chỉ mục (index bắt đầu từ 0):

echo "${inventory[1]}"  # in ra "băng"

Dùng chỉ mục âm để lấy phần tử từ cuối:

echo "${inventory[-1]}"  # in ra "sấm"

Kiểm tra độ dài mảng:

count=${#inventory[@]}
echo "Số lượng: $count"

Duyệt mảng

Sử dụng vòng lặp for để duyệt toàn bộ phần tử:

for item in "${inventory[@]}"; do
    printf "Vật phẩm: %s\n" "$item"
done

Thao tác động trên mảng

Thêm phần tử:

inventory+=("gió")

Sửa giá trị:

inventory[0]="nước"

Xóa phần tử:

unset inventory[1]

Lưu ý: sau khi xóa, chỉ mục không được tái sắp xếp. Để có mảng liên tục, nên xây dựng lại:

temp=()
for i in "${!inventory[@]}"; do
    temp+=("${inventory[i]}")
done
inventory=("${temp[@]}")

Cắt lát mảng (slicing)

Lấy một đoạn con từ mảng:

subset=("${inventory[@]:1:2}")  # từ index 1, lấy 2 phần tử

Nên kiểm tra độ dài trước khi cắt để tránh tràn:

if (( ${#inventory[@]} >= 3 )); then
    subset=("${inventory[@]:1:2}")
fi

Mảng kết hợp (associative arrays)

Mảng kết hợp ánh xạ chuỗi khóa sang giá trị, yêu cầu khai báo bằng declare -A:

declare -A stats
stats=( ["hp"]=100 ["mp"]=50 )

Thêm hoặc cập nhật cặp khóa-giá trị:

stats["stamina"]=80

Truy xuất giá trị:

echo "${stats["hp"]}"

Kiểm tra sự tồn tại của khóa trước khi truy cập:

if [[ -v stats["mp"] ]]; then
    echo "MP: ${stats["mp"]}"
fi

Xóa một khóa:

unset stats["stamina"]

Duyệt toàn bộ mảng kết hợp:

for key in "${!stats[@]}"; do
    printf "%s = %s\n" "$key" "${stats[$key]}"
done

Sử dụng mảng trong vòng lặp

Kết hợp mảng với điều kiện để xử lý linh hoạt:

for item in "${inventory[@]}"; do
    if [[ "$item" == "nước" ]]; then
        echo "Phát hiện nước – chống cháy!"
    fi
done

Vòng lặp while hữu ích khi cần xử lý mảng đến khi rỗng:

while (( ${#inventory[@]} > 0 )); do
    current="${inventory[0]}"
    echo "Xử lý: $current"
    unset inventory[0]
    # Tái lập mảng để dồn chỉ mục
    inventory=("${inventory[@]}")
done

Tối ưu hiệu năng

- Tránh gọi ${#array[@]} lặp đi lặp lại trong vòng lặp; lưu vào biến tạm.
- Đóng gói thao tác mảng (thêm, xóa, tìm kiếm) vào hàm để tái sử dụng.
- Luôn bao phần tử bằng dấu ngoặc kép "${arr[@]}" để xử lý đúng chuỗi chứa khoảng trắng.

Thẻ: Bash shell-scripting arrays associative-arrays linux-automation

Đăng vào ngày 31 tháng 7 lúc 01:46