Mảng (array) là một khái niệm cơ bản nhưng vô cùng quan trọng trong lập trình Bash. Việc nắm vững cách sử dụng mảng sẽ giúp bạn viết các script hiệu quả, linh hoạt và dễ bảo trì hơn. Trong bài viết này, Vietnix sẽ đồng hành cùng bạn khám phá thế giới mảng trong Bash, trang bị kiến thức từ A đến Z để bạn tự tin làm chủ Bash Array.
Mảng trong Bash là gì?
Mảng trong Bash là một danh sách các giá trị được lưu trữ dưới một biến duy nhất. Các giá trị trong mảng được gọi là phần tử, được quản lý và truy xuất thông qua chỉ mục.
Không giống như các ngôn ngữ lập trình như C hoặc C++, các mảng Bash hoạt động như một bộ nhớ một chiều cho các kiểu dữ liệu đa dạng. Ví dụ, một mảng trong Bash có thể sắp xếp dữ liệu số và chuỗi một cách đồng thời theo một cấu trúc có trật tự. Điểm mạnh của mảng trong Bash còn nằm ở khả năng tự động thay đổi kích thước và phân bổ bộ nhớ.
Không những là môi trường ứng dụng Array, Bash còn là môi trường hỗ trợ dòng lệnh (shell) trong việc thực hiện các tập lệnh (script) – chạy tập lệnh Bash. Ngoài ra, Bash còn đóng vai trò là một dòng lệnh hữu ích trên hệ điều hành Linux – lệnh Bash.
Bên cạnh đó, bạn có thể tìm hiểu thêm: Bash có phải là ngôn ngữ lập trình
5 ứng dụng của mảng trong Bash
Mảng trong Bash có thể được ứng dụng trong nhiều trường hợp, bao gồm:
- Lưu trữ dữ liệu: Mảng là công cụ hiệu quả để lưu trữ thông tin trong các script shell, cho phép thao tác dữ liệu một cách linh hoạt.
- Quản lý cấu hình: Mảng có thể được sử dụng để quản lý cấu hình hệ thống trong các script Bash.
- Xử lý file: Mảng cho phép truy cập và xử lý nội dung của các file một cách hiệu quả.
- Quản lý tiến trình và dịch vụ: Mảng có thể lưu trữ và quản lý thông tin về tên dịch vụ, ID tiến trình và các thông tin liên quan khác trong các script quản trị hệ thống.
- Kiểm tra và xác thực dữ liệu: Mảng Bash có thể được dùng để kiểm tra xem dữ liệu nhập vào có đúng hay không. Ví dụ, bạn có thể kiểm tra tính hợp lệ của giá trị do người dùng nhập vào bằng cách so sánh với các giá trị trong mảng.
Các loại mảng trong Bash
Có hai loại mảng chính trong Bash:
- Mảng được lập chỉ mục (Numerically Indexed Array): Dạng mảng tham chiếu đến các phần tử dữ liệu bằng cách sử dụng chỉ số bắt đầu từ ‘0’. Vì vậy, nếu một mảng chứa hai phần tử, giá trị đầu tiên được đặt ở chỉ số 0 trong khi phần tử thứ hai (phần tử cuối cùng) ở chỉ số 1.
- Mảng kết hợp (Associative Array): Mảng kết hợp sử dụng chuỗi làm chỉ mục để truy xuất các giá trị.
Dựa trên số chiều, mảng trong Bash có thể được phân loại thành:
- Mảng một chiều (1-D Array): Đây là loại mảng phổ biến nhất, là một danh sách các giá trị, còn được gọi là mảng được lập chỉ số theo số. Loại mảng này được lập chỉ số bắt đầu từ 0 và các phần tử được truy cập thông qua các chỉ số.
- Mảng đa chiều (Multidimensional Array): Bash không hỗ trợ trực tiếp mảng đa chiều như Python hay C++. Tuy nhiên, bạn có thể mô phỏng mảng đa chiều bằng cách tạo một mảng chứa các mảng con, trong đó các phần tử được sắp xếp theo dạng lưới hoặc ma trận.
2 cách sử dụng cơ bản mảng trong Bash
Cách 1: Khai báo mảng trong Bash
Mặc dù Bash là ngôn ngữ script linh hoạt nhưng việc khai báo mảng là bước đầu tiên và quan trọng khi bạn muốn làm việc với mảng. Bạn có thể khai báo mảng trong Bash bằng cách sử dụng cú pháp sau với lệnh declare
:
declare -a <array_name>
Ví dụ dưới đây ta sẽ tạo một mảng có tên tennis_kit bằng cách sử dụng Bash Scripting như sau:
#!/bin/bash
#Declaring an indexed array using the declare command
declare -a tennis_kit
#print a message if no error occurs in the declaration
echo “index array declared”
Cách 2: In mảng trong Bash
In mảng là thao tác phổ biến trong lập trình Bash, giúp kiểm tra kết quả và hiển thị dữ liệu. Có nhiều cách để in toàn bộ nội dung của một mảng trong Bash. Dưới đây là hai cách phổ biến bằng lệnh echo:
echo ${array[@]}
Hoặc
echo ${array[*]}
Bạn có thể xem ví dụ chạy song song lệnh Bash bên dưới để hiểu rõ hơn:
#!/bin/bash
#Array declaration with elements
heroes=(Batman Ironman Spiderman)
#print contents only with @ operator
echo "using @: ${heroes[@]}"
#print arrays elements with string and * operator
echo "using *: ${heroes[*]}"
5 ví dụ về cách thao tác cơ bản với mảng trong Shell Script
Ví dụ 1: Duyệt qua mảng trong Bash
Khi làm việc với mảng trong Bash
, việc truy cập vào các phần tử của mảng là rất quan trọng. Bạn có thể sử dụng các phần tử để in ra hoặc thực hiện các thao tác khác trên mảng. Trong phần này, Vietnix sẽ hướng dẫn bạn cách truy cập các phần tử mảng bằng cách sử dụng chỉ số của chúng.
Như đã trình bày ở phần trước, chỉ số của mảng bắt đầu từ 0 và tăng dần lên 1. Ví dụ, để lấy giá trị của phần tử thứ hai trong mảng, bạn sử dụng đoạn code sau:
echo ${array_name[index_num]}
Chẳng hạn:
#!/bin/bash
#Declaring and initializing an indexed array
fruits=(apple, banana, grape)
#Access the first element
echo "first value: ${fruits[0]}"
#Access the second and last array elements
echo "second value: ${fruits[1]}"
echo "last value: ${fruits[2]}"
Ví dụ 2: In các phần tử cụ thể của một mảng trong Bash
Ngoài việc in toàn bộ mảng, bạn cũng có thể in ra các phần tử cụ thể bằng cách sử dụng chỉ số. Bạn hãy xem ví dụ sau:
#!/bin/bash
#Declaring and initializing an array
currency=(dollar taka rupee yen pound franc dinar dirham)
#print the second fifth and last elements
echo "total elements: ${#currency[@]} but printed only below ones:"
echo "${currency[1]}"
echo "${currency[4]}"
echo "${currency[7]}"
Trong hình trên, bạn có thể thấy kết quả đã in ra 3 phần tử cụ thể (phần tử thứ 2, thứ 5 và phần tử cuối cùng) từ mảng currency gồm 8 phần tử.
Ví dụ 3: Đo chiều dài của một mảng trong Bash
Mảng trong Bash khác với mảng trong Python ở chỗ mảng có thể thay đổi kích thước. Khi bạn thêm phần tử vào mảng, chiều dài sẽ tự động tăng lên. Để quản lý bộ nhớ hiệu quả, việc biết chiều dài hiện tại của mảng rất quan trọng.
Để tìm chiều dài của một mảng, bạn chỉ cần thêm dòng lệnh sau vào shell script của mình:
echo ${#arr_name[@]}
length= ${#arr_name[@]}
echo $length
Ví dụ:
#!/bin/bash
#Array creation
cards=(hearts diamonds spades clubs)
#Array length calculation and assigning to a new variable named len
len=${#cards[@]}
#printing array length to the prompt
echo $len
Script Bash trên đã hiển thị thành công độ dài của mảng cards ra màn hình.
Ví dụ 4: Lặp qua các phần tử mảng trong Bash
Để truy cập và in các phần tử của mảng Bash, cách thường dùng nhất là sử dụng chỉ số. Bạn cũng có thể sử dụng vòng lặp for để truy cập các phần tử mảng bằng cú pháp sau:
for items in ${arr_name[@]}
do
echo $items
done
Ví dụ:
#!/bin/bash
#Declaring an indexed array and assigning it with values
fruits=(apple banana grape)
#looping through the elements to print
for elems in ${fruits[@]}
do
echo $elems
done
Chương trình này sử dụng vòng lặp for để in ra các giá trị của mảng fruits một cách tuần tự.
Ví dụ 5: Xóa mảng trong Bash
Nếu bạn muốn xóa toàn bộ một mảng sau khi hoàn thành các tác vụ cần thiết, bạn sử dụng lệnh unset. Tuy nhiên, cú pháp sử dụng unset để xóa mảng khác (hủy cài đặt với một biến trong môi trường Linux) so với xóa từng phần tử.
Trong trường hợp này, bạn không chỉ định chỉ số phần tử như khi xóa từng phần tử.
Script ví dụ:
#!/bin/bash
# the array to be deleted
language=(c python Golang java)
#deleting the entire array
unset language
#printing array elements
echo ${language[@]}
#printing array indices
echo ${!language[@]}
Sau khi chạy đoạn script trên, máy tính sẽ không hiển thị gì trên màn hình cả. Điều này chứng tỏ mảng language
đã bị xóa thành công.
6 thao tác khác với mảng trong Bash
Thêm phần tử vào mảng trong Bash
Để thêm phần tử vào mảng trong Bash, bạn sử dụng toán tử += với cú pháp như sau:
array_name+=(element to be appended)
Ví dụ:
#!/bin/bash
#The main array
distros=(ubuntu kali arch)
#prints array with 3 existing elements
echo "array before appending: ${distros[@]}"
#new value to append
distros+=(redHat)
#Prints array with newly added element redHat
echo "array after appending: ${distros[@]}"
Chèn phần tử vào mảng trong Bash
Để chèn phần tử vào một vị trí cụ thể trong mảng, bạn sử dụng cú pháp sau:
array_name[position]= element to be inserted
Ví dụ:
#!/bin/bash
#The primary array
bd_bands=(artcell rockStrata warfaze)
#inserting elements into the array at different positions
bd_bands[4]=vibe
bd_bands[10]=powersurge
# loop through the indices and print elements
for position in ${!bd_bands[@]};
do
echo "band ${bd_bands[$position]} is at index: $position"
done
echo "Hence, the currently busy indices are: ${!bd_bands[@]"
Kết quả: Mảng bd_bands
sẽ có các phần tử được chèn vào vị trí mong muốn. Các chỉ số được in ra sẽ cho thấy vị trí của các phần tử trong mảng.
Cập nhật phần tử mảng trong Bash
Để cập nhật giá trị của một phần tử trong mảng, bạn sử dụng cú pháp sau:
example_array[index]=updated element
Ví dụ:
#!/bin/bash
#The actual array
topGun=(call sign ROOSTER)
#print the array
echo "before updation: ${topGun[@]}"
#update the array
topGun[2]=MAVERICK
#print the array with updated elements at index 2
echo "after updation: ${topGun[@]}"
Kết quả: Mảng topGun
sẽ có phần tử thứ 3 được cập nhật thành giá trị mới.
Xóa phần tử khỏi mảng trong Bash
Để xóa một phần tử trong mảng, bạn sử dụng lệnh unset với cú pháp như sau:
unset example_array[index]
Ví dụ:
#!/bin/bash
# the array
brands=(adidas puma nike)
#print array
echo "before removal: ${brands[@]}"
# Deleting nike from the array
unset brands[2]
#printing the array after removal of the element nike
echo "after removal: ${brands[@]}"
Kết quả: Mảng brands
sẽ không còn chứa phần tử nike.
Cắt mảng trong Bash
Khi bạn có một mảng dài trong Bash và muốn truy cập vào một số phần tử nhất định, bạn có thể sử dụng kỹ thuật Array Slicing (cắt mảng). Cú pháp thực hiện như sau:
${array_name[@]:X:Y}
Ví dụ:
#!/bin/bash
#the actual array
food=(pizza burger sandwich hotdog pasta chicken)
#print the array
echo "original elements: ${food[@]}"
#slicing the array
sliced=${food[@]:2:3}
#printing the sliced elements
echo "sliced elements: $sliced"
Gộp 2 mảng trong Bash
Để gộp 2 mảng thành 1 mảng mới, bạn sử dụng toán tử mở rộng mảng ${array[@]}
với cú pháp như sau:
merged_array=(${array1[@]} ${array2[@]})
Ví dụ:
#!/bin/bash
#The two arrays to be combined
movie1=(Inception Insomnia Prestige)
movie2 =(Dunkirk Tenet Oppenheimer)
#The merge of arrays
merged_array=(${movie1[@]} ${movie2[@]})
#print the seperate arrays
echo "movie1: ${merged_array[@]}"
echo "movie2: ${merged_array[@]}"
#print the merged array
echo "merged_array: ${merged_array[@]}"
Kết quả: Mảng merged_array
sẽ chứa tất cả các phần tử của 2 mảng ban đầu.
Ví dụ:
merged_array=(${movie1[@]} ${movie2[@]})
merged_no_space=(${movie1[@]}${movie2[@]})
Kết quả:
4 ví dụ thực tế về cách sử dụng mảng trong Bash Script
Ví dụ 1: Đọc nội dung file vào mảng trong Bash
Để đọc nội dung của 1 file vào mảng, bạn sử dụng script Bash sau:
#!/bin/bash
echo “Enter the file_name you want to read”
read file # takes the file name as input from the user
array_of_file=( $(cat $file) ) # file contents are now assigned as array elements
#read the contents from the array
echo “the content of the file: $array_of_file[@]”
Kết quả: Mảng array_of_file
sẽ chứa các dòng của file đã đọc.
Ví dụ 2: Sắp xếp mảng trong Bash với thuật toán Bubble Sort (sắp xếp nổi bọt)
Sắp xếp là một thao tác quan trọng trong lập trình, giúp cho việc truy xuất và phân tích dữ liệu trở nên hiệu quả hơn. Trong ví dụ này, Vietnix sẽ giới thiệu đến bạn cách triển khai thuật toán Bubble Sort (sắp xếp nổi bọt) trên mảng trong Bash.
Bubble Sort là thuật toán sắp xếp dễ hiểu nhất, hoạt động dựa trên việc so sánh các phần tử liền kề. Nếu hai phần tử liền kề không theo thứ tự mong muốn (tăng dần hoặc giảm dần), cả hai phần tử sẽ được hoán đổi vị trí. Quá trình này được lặp lại cho đến khi toàn bộ mảng được sắp xếp theo đúng thứ tự.
Để sắp xếp mảng Bash bằng Bubble Sort, bạn sử dụng script Bash sau:
#!/bin/bash
# The unsorted array
numbers=(2 3 1 5 4)
# array length
len=${#numbers[@]}
#print the unsorted array
echo “unsorted array: ${numbers[@]}”
#accessing elements of the array
for ((i=0; i<len; i++))
do
#comparing & swapping array elements
for ((j=0;j<len-i-1; j++))
do
if [ ${numbers[j]} -gt ${numbers[$((j+1))]} ]
then
temp=${numbers[j]}
numbers[$j]=${numbers[$((j+1))]}
number[$((j+1))]=$temp
fi
done
done
#print the sorted array
echo “sorted array: ${numbers[@]}”
Kết quả: Script trên đã sắp xếp mảng numbers theo thứ tự tăng dần.
Ví dụ 3: Tìm kiếm tuyến tính (Linear Search) trong mảng Bash
Tìm kiếm tuyến tính là một thuật toán tìm kiếm đơn giản trong mảng. Thuật toán này hoạt động bằng cách lặp qua từng phần tử của mảng và kiểm tra xem phần tử đó có khớp với giá trị cần tìm hay không.
Để tìm kiếm một phần tử cụ thể trong mảng Bash bằng tìm kiếm tuyến tính, sử dụng script Bash sau:
#!/bin/bash
#the array
array=(1 2 4 5 7)
#print the array
echo “the array: ${array[@]}”
# array length
len=${#array[@]}
# taking user input the element to search for
echo “enter the element to search”
read item
flag=0 # initializing a variable to track the desired element
# loop through the array and locate the element
for ((i=0; i<len; i++))
do
if [ ${array[$i]} -eq $item ]; then
echo “the item ${array[$i]} is at position $i”
flag=1 # indicates that the item is found
break # exit the loop immediately as the item is already found
fi
done
#if not found then alert
if [ $flag -eq 0 ]; then
echo “the item is not present in the array”
fi
Kết quả: Script này sẽ tìm kiếm giá trị được nhập bởi người dùng trong mảng. Nếu tìm thấy sẽ in ra vị trí của giá trị đó. Nếu không tìm thấy sẽ thông báo rằng giá trị đó không có trong mảng.
Ví dụ 4: Mô phỏng mảng đa chiều trong Bash
Bash chủ yếu hỗ trợ mảng một chiều và không có kiểu dữ liệu mảng đa chiều. Tuy nhiên, bạn có thể mô phỏng mảng đa chiều bằng cách sử dụng vòng lặp for trong Bash.
Ví dụ:
#!/bin/bash
# array declaration with no elements
declare -a matrices
#array dimension user input
echo “enter the number of rows:”
read row
echo “enter the number of columns:”
read cols
#looping through the rows and columns
for ((x=0; x<row; x++))
do
for ((y=0; y<cols; y++))
do
matrices[“$x, $y”]=$RANDOM # assigning random numbers to each position of the array
done
done
#print the multidimensional array
for ((x=0; x<row: x++))
do
for ((y=0: y<cols;y++))
do
echo -ne “${matrices[$x, $y]}\t”
done
echo # prints each row in a new line according to the user input dimensions
done
Kết quả: Script sẽ in ra một mảng đa chiều với số hàng và số cột do người dùng nhập vào, mỗi phần tử của mảng sẽ chứa một số ngẫu nhiên. Đoạn script bash ở trên in ra một mảng đa chiều có 2 hàng và 3 cột .
Câu hỏi thường gặp
Mảng trong Bash có thể chứa các loại dữ liệu khác nhau không?
Hoàn toàn có thể. Mảng trong Bash có một đặc điểm rất linh hoạt, đó là không yêu cầu khai báo kiểu dữ liệu cho các phần tử.
Có thể thay đổi giá trị của các phần tử trong một mảng sau khi tạo không?
Có thể. Bạn có thể thay đổi bằng cách truy cập vào phần tử và gán giá trị mới.
Lời kết
Bài viết đã cung cấp cho bạn một cái nhìn tổng quan về mảng trong Bash, bao gồm cách tạo, truy cập, thao tác và ứng dụng của mảng trong các kịch bản Bash. Hy vọng những kiến thức này sẽ giúp bạn sử dụng mảng một cách hiệu quả trong công việc của mình.