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.