Một mảng là một biến chứa nhiều giá trị có thể cùng kiểu hoặc khác kiểu. Không có giới hạn tối đa cho kích thước mảng, cũng không yêu cầu biến thành viên phải được chỉ mục hoặc gán liên tục. Chỉ mục mảng bắt đầu từ 0.
Trong bài này, chúng ta sẽ xem lại 15 thao tác mảng khác nhau trong bash.
Bài viết này là một phần của loạt bài hướng dẫn Bash đang diễn ra. Cho những người mới với bash scripting, hãy bắt đầu từ hướng dẫn Bash Scripting Introduction.
1. Khai Báo Mảng Và Gán Giá Trị
Trong bash, mảng được tạo tự động khi biến được dùng ở định dạng như,
name[index]=value
namelà bất kỳ tên nào cho mảngindexcó thể là bất kỳ số hoặc biểu thức nào phải đánh giá thành số lớn hơn hoặc bằng 0. Bạn có thể khai báo mảng tường minh dùngdeclare -a arrayname.
$ cat arraymanip.sh
#! /bin/bash
Unix[0]='Debian'
Unix[1]='Red hat'
Unix[2]='Ubuntu'
Unix[3]='Suse'
echo ${Unix[1]}
$./arraymanip.sh
Red hat
Để truy cập phần tử từ mảng, dùng ngoặc nhọn như ${name[index]}.
2. Khởi Tạo Mảng Khi Khai Báo
Thay vì khởi tạo từng phần tử mảng riêng biệt, bạn có thể khai báo và khởi tạo mảng bằng cách chỉ định danh sách phần tử (phân tách bằng khoảng trắng) trong ngoặc nhọn.
Syntax: declare -a arrayname=(element1 element2 element3)
Nếu phần tử có ký tự khoảng trắng, bao quanh nó bằng dấu ngoặc kép.
#! /bin/bash
$cat arraymanip.sh
declare -a Unix=('Debian' 'Red hat' 'Red hat' 'Suse' 'Fedora');
declare -a khai báo mảng và tất cả phần tử trong ngoặc đơn là phần tử của mảng.
3. In Toàn Bộ Mảng Bash
Có cách khác nhau để in toàn bộ phần tử mảng. Nếu số chỉ mục là @ hoặc *, tất cả thành viên mảng được tham chiếu. Bạn có thể duyệt qua các phần tử mảng và in nó, dùng câu lệnh lặp trong bash.
echo ${Unix[@]}
# Add the above echo statement into the arraymanip.sh
#./t.sh
Debian Red hat Ubuntu Suse
Tham chiếu nội dung biến thành viên mảng không cung cấp số chỉ mục giống như tham chiếu nội dung phần tử đầu tiên, phần tử được tham chiếu với số chỉ mục 0.
4. Độ Dài Mảng Bash
Chúng ta có thể lấy độ dài mảng dùng tham số đặc biệt $#.
${#arrayname[@]} cho độ dài mảng.
$ cat arraymanip.sh
declare -a Unix=('Debian' 'Red hat' 'Suse' 'Fedora');
echo ${#Unix[@]} # Number of elements in the array
echo ${#Unix} # Number of characters in the first element of the array.i.e Debian
$./arraymanip.sh
4
6
5. Độ Dài Phần Tử Thứ n Trong Mảng
${#arrayname[n]} nên cho độ dài phần tử thứ n trong mảng.
$cat arraymanip.sh
#! /bin/bash
Unix[0]='Debian'
Unix[1]='Red hat'
Unix[2]='Ubuntu'
Unix[3]='Suse'
echo ${#Unix[3]} # length of the element located at index 3 i.e Suse
$./arraymanip.sh
4
6. Trích Xuất Theo Offset Và Độ Dài Cho Mảng
Ví dụ sau chỉ cách trích xuất 2 phần tử bắt đầu từ vị trí 3 từ mảng tên Unix.
$cat arraymanip.sh
Unix=('Debian' 'Red hat' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux');
echo ${Unix[@]:3:2}
$./arraymanip.sh
Suse Fedora
Ví dụ trên trả về phần tử ở chỉ mục 3 và chỉ mục 4. Chỉ mục luôn bắt đầu từ 0.
7. Trích Xuất Với Offset Và Độ Dãi, Cho Phần Tử Cụ Thể Của Mảng
Để trích xuất chỉ 4 ký tự đầu từ phần tử mảng. Ví dụ, Ubuntu ở chỉ mục thứ 2 của mảng, bạn có thể dùng offset và độ dài cho phần tử cụ thể của mảng.
$cat arraymanip.sh
#! /bin/bash
Unix=('Debian' 'Red hat' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux');
echo ${Unix[2]:0:4}
./arraymanip.sh
Ubun
Ví dụ trên trích xuất 4 ký tự đầu từ phần tử chỉ mục 2 của mảng.
8. Tìm Kiếm Và Thay Thế Trong Phần Tử Mảng
Ví dụ sau, tìm Ubuntu trong phần tử mảng, và thay thế bằng từ 'SCO Unix'.
$cat arraymanip.sh
#!/bin/bash
Unix=('Debian' 'Red hat' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux');
echo ${Unix[@]/Ubuntu/SCO Unix}
$./arraymanip.sh
Debian Red hat SCO Unix Suse Fedora UTS OpenLinux
Trong ví dụ này, nó thay thế phần tử ở chỉ mục 2 'Ubuntu' với 'SCO Unix'. Nhưng ví dụ này sẽ không thay thế vĩnh viễn nội dung mảng.
9. Thêm Phần Tử Vào Mảng Bash Hiện Có
Ví dụ sau chỉ cách thêm phần tử vào mảng hiện có.
$cat arraymanip.sh
Unix=('Debian' 'Red hat' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux');
Unix=("${Unix[@]}" "AIX" "HP-UX")
echo ${Unix[7]}
$./arraymanip.sh
AIX
Trong mảng tên Unix, phần tử 'AIX' và 'HP-UX' được thêm ở chỉ mục 7 và 8 tương ứng.
10. Xóa Phần Tử Khỏi Mảng
unset dùng để xóa phần tử khỏi mảng. unset sẽ có hiệu quả như gán null cho phần tử.
$cat arraymanip.sh
#!/bin/bash
Unix=('Debian' 'Red hat' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux');
unset Unix[3]
echo ${Unix[3]}
Script trên chỉ in null là giá trị có sẵn ở chỉ mục 3. Ví dụ sau chỉ một cách để xóa phần tử hoàn toàn khỏi mảng.
$ cat arraymanip.sh
Unix=('Debian' 'Red hat' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux');
pos=3
Unix=(${Unix[@]:0:$pos} ${Unix[@]:$(($pos + 1))})
echo ${Unix[@]}
$./arraymanip.sh
Debian Red hat Ubuntu Fedora UTS OpenLinux
Trong ví dụ này, ${Unix[@]:0:$pos} cho 3 phần tử bắt đầu từ chỉ mục 0 tức 0,1,2 và ${Unix[@]:4} cho phần tử từ chỉ mục 4 đến cuối. Và gộp cả hai đầu ra trên. Đây là một cách giải quyết để xóa phần tử khỏi mảng.
11. Xóa Phần Tử Mảng Bash Dùng Mẫu (Pattern)
Trong điều kiện tìm kiếm bạn có thể đưa mẫu, và lưu phần tử còn lại vào mảng khác như dưới.
$ cat arraymanip.sh
#!/bin/bash
declare -a Unix=('Debian' 'Red hat' 'Ubuntu' 'Suse' 'Fedora');
declare -a patter=( ${Unix[@]/Red*/} )
echo ${patter[@]}
$ ./arraymanip.sh
Debian Ubuntu Suse Fedora
Ví dụ trên xóa phần tử có mẫu Red*.
12. Sao Chép Mảng
Mở rộng phần tử mảng và lưu vào mảng mới như dưới.
#!/bin/bash
Unix=('Debian' 'Red hat' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux');
Linux=("${Unix[@]}")
echo ${Linux[@]}
$ ./arraymanip.sh
Debian Red hat Ubuntu Fedora UTS OpenLinux
13. Nối Hai Mảng Bash
Mở rộng phần tử hai mảng và gán cho mảng mới.
$cat arraymanip.sh
#!/bin/bash
Unix=('Debian' 'Red hat' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux');
Shell=('bash' 'csh' 'jsh' 'rsh' 'ksh' 'rc' 'tcsh');
UnixShell=("${Unix[@]}" "${Shell[@]}")
echo ${UnixShell[@]}
echo ${#UnixShell[@]}
$ ./arraymanip.sh
Debian Red hat Ubuntu Suse Fedora UTS OpenLinux bash csh jsh rsh ksh rc tcsh
14
Nó in mảng có phần tử của cả mảng 'Unix' và 'Shell', và số phần tử mảng mới là 14.
14. Xóa Toàn Bộ Mảng
unset dùng để xóa toàn bộ mảng.
$cat arraymanip.sh
#!/bin/bash
Unix=('Debian' 'Red hat' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux');
Shell=('bash' 'csh' 'jsh' 'rsh' 'ksh' 'rc' 'tcsh');
UnixShell=("${Unix[@]}" "${Shell[@]}")
unset UnixShell
echo ${#UnixShell[@]}
$ ./arraymanip.sh
0
Sau unset mảng, độ dài của nó sẽ là 0 như trên.
15. Nạp Nội Dung File Vào Mảng
Bạn có thể nạp nội dung file dòng per dòng vào mảng.
#Example file
$ cat logfile
Welcome to thegeekstuff
Linux
Unix
$ cat loadcontent.sh
#!/bin/bash
filecontent=( \`cat "logfile" \` )
for t in "${filecontent[@]}"
do
echo $t
done
echo "Read file content!"
$ ./loadcontent.sh
Welcome
to
thegeekstuff
Linux
Unix
Read file content!
Trong ví dụ trên, mỗi chỉ mục phần tử mảng đã in qua vòng lặp for.
Đọc Thêm
Bash 101 Hacks, tác giả Ramesh Natarajan. Tôi dành hầu hết thời gian trên môi trường Linux. Vì vậy, tự nhiên tôi là fan hâm mộ lớn của dòng lệnh Bash và shell scripting. 15 năm trước, khi tôi làm việc trên các hương *nix khác nhau, tôi thường viết nhiều mã trên C shell và Korn shell. Những năm sau, khi bắt đầu làm quản trị hệ thống trên Linux, tôi khá nhiều tự động hóa mọi tác vụ có thể bằng Bash shell scripting. Dựa trên kinh nghiệm Bash, tôi đã viết eBook Bash 101 Hacks chứa 101 ví dụ thực tế về cả dòng lệnh Bash và shell scripting. Nếu bạn đang suy nghĩ về việc thành thạo Bash, hãy làm ơn đọc cuốn sách này, nó sẽ giúp bạn kiểm soát dòng lệnh Bash và shell scripting của mình.