陣列簡介
在bash腳本編程當中,變數是存盤單個元素的記憶體空間;而陣列是存盤多個元素的一段連續的記憶體空間,
陣列由陣列名和下標構成,如下,
ARRAY_NAME[SUBSCRIPT]
陣列按照下標的型別可分為兩種:
- 索引(indexed)陣列:下標為0、1、2等非負整數,
- 關聯(associative)陣列:下標為用戶自定義的字串,
陣列的操作
宣告
索引陣列可以不宣告直接使用;而關聯陣列如果不宣告直接使用的話,會被認為是索引陣列,即使它的下標是字串,
索引陣列的宣告方式,
# declare -a ARRAY_NAME
關聯陣列的宣告方式,
# declare -A ARRAY_NAME
賦值
一次只賦值一個元素,
# ARRAY_NAME[SUBSCRIPT]=VALUE
一次賦值全部元素,
# ARRAY_NAME = ("VAL1" "VAL2" "VAL3" ...)
一次賦值多個可以是不連續的元素,
# ARRAY_NAME = ([0] = "VAL1" [3] = "VAL3")
像這種不要求元素必須依次存在的陣列(即可以在沒有A[1]和A[2]的時候就賦值A[3]),叫做稀疏格式陣列,因此,bash支持稀疏格式的陣列,
讀取標準輸入賦值陣列,
# read -a ARRAY_NAME
在輸入的時候,以空格作為元素的分隔符,以回車鍵結束元素的賦值,
向陣列的末尾追加元素,
ARRAY_NAME[${#ARRAY_NAME[@]}]=VALUE
或者
ARRAY_NAME+=(VALUE)
參考
參考單個陣列元素,
${ARRAY_NAME[SUBSCRIPT]}
如果省略SUBSCRIPT,那么就等同于SUBSCRIPT=0,即以下兩個參考是相同的,
${ARRAY_NAME[0]}
${ARRAY_NAME}
下標可以是一個變數,當下標是一個變數的時候,可以省略掉展開下標變數字符“$”,即${array[$var]}=${array[var]},
[root@c7-server ~]# declare -a name=(bu jing yun) [root@c7-server ~]# echo ${name[*]} bu jing yun [root@c7-server ~]# declare -i a=0 b=1 c=2 [root@c7-server ~]# echo ${name[$a]} bu [root@c7-server ~]# echo ${name[$b]} jing [root@c7-server ~]# echo ${name[$c]} yun [root@c7-server ~]# echo ${name[a]} bu [root@c7-server ~]# echo ${name[b]} jing [root@c7-server ~]# echo ${name[c]} yun
參考陣列的所有元素,正常情況下,二者沒有區別,只有當被雙引號包裹的時候,“@”被展開為每個元素為一個獨立的單詞;“*”被展開為所有元素為一個統一的單詞,
${ARRAY_NAME[@]}
${ARRAY_NAME[*]}
參考陣列元素的長度,
${#ARRAY_NAME[SUBSCRIPT]}
參考陣列的長度,即陣列的元素個數,
${#ARRAY_NAME[@]}
${#ARRAY_NAME[*]}
參考陣列的部分元素(切片),
${ARRAY_NAME[@]:OFFSET:NUMBER}
${ARRAY_NAME[*]:OFFSET:NUMBER}
OFFSET:偏移,表示偏移/跳過陣列中的前幾個元素,
NUMBER:表示偏移后取幾個元素,
如果省略了NUMBER,并且OFFSET的值為“ -n”(注意,-n的左邊有空格),則表示參考倒數的n個元素,
截止目前我們參考的都是陣列的值,如果我們想參考陣列的下標的話,可以使用:
${!ARRAY_NAME[@]}
${!ARRAY_NAME[*]}
洗掉
洗掉陣列元素,
# unset ARRAY_NAME[SUBSCRIPT]
洗掉陣列,
# unset ARRAY_NAME
陣列示例
定義一個索引陣列,逐一賦值陣列元素,
[root@c7-server ~]# declare -a my_array [root@c7-server ~]# my_array[0]=zhang [root@c7-server ~]# my_array[1]=wen [root@c7-server ~]# my_array[2]=long
根據陣列下標獲取陣列元素,留意我們上文說的,當參考陣列不帶下標的時候,等同于參考${ARRAY_NAME[0]},
[root@c7-server ~]# echo ${my_array} zhang [root@c7-server ~]# echo ${my_array[0]} zhang [root@c7-server ~]# echo ${my_array[1]} wen [root@c7-server ~]# echo ${my_array[2]}
long
參考陣列中的所有元素,順便測驗一下“@”和“*”的區別,注意,這個區別,僅在${my_array[@]}或者${my_array[*]}被雙引號包裹的情況下才會出現,
[root@c7-server ~]# echo ${my_array[@]} zhang wen long [root@c7-server ~]# echo ${my_array[*]} zhang wen long [root@c7-server ~]# for i in "${my_array[@]}"; do echo $i; done zhang wen long [root@c7-server ~]# for i in "${my_array[*]}"; do echo $i; done zhang wen long
參考陣列個數,
[root@c7-server ~]# echo ${#my_array[@]} 3 [root@c7-server ~]# echo ${#my_array[*]} 3
參考陣列中元素的個數,
[root@c7-server ~]# echo ${my_array[0]} zhang [root@c7-server ~]# echo ${#my_array[0]} 5
接下來演示其他幾種不同的賦值方式,操作前可先洗掉陣列,
[root@c7-server ~]# unset my_array [root@c7-server ~]# my_array=([0]=zhang [1]=wen [2]=long) [root@c7-server ~]# echo ${my_array[@]} zhang wen long [root@c7-server ~]# unset my_array [root@c7-server ~]# read -a my_array Mon Tue Wed Thu Fri Sat Sun [root@c7-server ~]# echo ${my_array[@]} Mon Tue Wed Thu Fri Sat Sun
陣列元素去子串(substring),即切片,
[root@c7-server ~]# echo ${my_array[@]} Mon Tue Wed Thu Fri Sat Sun [root@c7-server ~]# echo ${my_array[@]:3:2} Thu Fri [root@c7-server ~]# echo ${my_array[@]:2:3} Wed Thu Fri [root@c7-server ~]# echo ${my_array[@]: -3} Fri Sat Sun
陣列元素追加,
[root@c7-server ~]# echo ${my_array[@]} Mon Tue Wed Thu Fri Sat Sun [root@c7-server ~]# my_array+=(ddd) [root@c7-server ~]# my_array[${#my_array[@]}]=eee [root@c7-server ~]# echo ${my_array[@]} Mon Tue Wed Thu Fri Sat Sun ddd eee
參考陣列的下標(subscript),個人感覺參考陣列下標在關聯陣列中比較有用,在索引陣列中用處不大,
[root@c7-server ~]# echo ${!my_array[@]} 0 1 2 3 4 5 6 7 8 [root@c7-server ~]# unset my_array [root@c7-server ~]# declare -A my_array [root@c7-server ~]# my_array=([name]=zwl [age]=28 [sex]=male) [root@c7-server ~]# echo ${my_array[@]} zwl 28 male [root@c7-server ~]# echo ${!my_array[@]} name age sex
練習題
題一:生成10個100以內的非負整數并存入陣列當中,對其進行排序然后輸出最大值和最小值,
這道題,涉及到演算法中的冒泡排序,可以參考一下《冒泡排序_百度百科》中的概念解釋,以及《1.1 冒泡排序 | 菜鳥教程》中的圖示,這個GIF圖真的超棒!
按照升序排序后,最大值和最小值取頭尾即可,
代碼示例,
#!/bin/bash declare -a rand declare -i rand_length var for i in {0..9}; do rand[$i]=$((RANDOM%100)) done echo -e "The original array is \t${rand[*]}." rand_length=${#rand[*]} #echo $rand_length for i in $(seq 0 $((rand_length-1)) | sort -nr); do for((j=0;j<$i;j++)); do if [ ${rand[j]} -gt ${rand[((j+1))]} ]; then var=${rand[j]} rand[j]=${rand[j+1]} rand[j+1]=$var fi done #echo ${rand[*]} done echo -e "The last array is \t${rand[*]}." echo "The min of the array is ${rand[0]}." echo "The max of the array is ${rand[-1]}."
結果演示,
[root@c7-server ~]# bash arrayBubbleSort.sh The original array is 89 71 5 61 64 81 32 32 44 58. The last array is 5 32 32 44 58 61 64 71 81 89. The min of the array is 5. The max of the array is 89. [root@c7-server ~]# bash arrayBubbleSort.sh The original array is 17 41 81 62 94 97 37 11 11 41. The last array is 11 11 17 37 41 41 62 81 94 97. The min of the array is 11. The max of the array is 97. [root@c7-server ~]# bash arrayBubbleSort.sh The original array is 44 38 38 58 44 36 41 66 85 76. The last array is 36 38 38 41 44 44 58 66 76 85. The min of the array is 36. The max of the array is 85.
看懂代碼以后,我們可以調整一下echo陳述句,就可以看到每次回圈排序的結果,
The original array is 57 68 10 50 34 98 52 21 83 36. 57 10 50 34 68 52 21 83 36 98 10 50 34 57 52 21 68 36 83 98 10 34 50 52 21 57 36 68 83 98 10 34 50 21 52 36 57 68 83 98 10 34 21 50 36 52 57 68 83 98 10 21 34 36 50 52 57 68 83 98 10 21 34 36 50 52 57 68 83 98 10 21 34 36 50 52 57 68 83 98 10 21 34 36 50 52 57 68 83 98 10 21 34 36 50 52 57 68 83 98
從結果中我們也會發現,除非是剛好是倒序的情況,否則在回圈的中途就可以排序完成了,
這個腳本,個人覺得還是會稍微難點的,尤其是對于演算法基礎薄弱且非編程的人員,我也是Google后才知道結果的,真的搞不懂的同學,不必糾結,將來再補演算法即可,這篇隨筆主要是了解陣列的,
題二:定義一個陣列,陣列元素為/var/log/目錄下所有以.log結尾的檔案的檔案名;統計下標為偶數的檔案的行數并求和,
#!/bin/bash declare -a filePool=(/var/log/*.log) declare -i sum=0 declare -i line for i in $(seq 0 $((${#filePool[*]}-1))); do if [ $((i%2)) -eq 0 ]; then line=$(wc -l ${filePool[i]} | cut -d " " -f 1) ((sum+=line)) fi done echo "The sum of lines which meet the conditions is $sum."
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/149741.html
標籤:Linux
