亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

Shell 數組

1. Shell 數組概述

我們學習了變量,知道了變量為存儲單個元素的最小單元,本節我們來學習數組來存放多個元素的集合。

1.1 Shell 數組是什么

顧名思義,數組就是一系列數據的集合,這個數據就是我們之前學習的存儲單個元素的最小單元變量,也就是說將一些列的元素整合到一個集合內,這個集合的名稱就叫數組。當然與其他語言一樣,數組具備幾個條件,在 Shell 中數組僅支持一維數組,數組元素的下標從 0 開始,數組元素沒有最大限制等。

1.2 為什么要用數組

與變量類似,當我們操作批量數據的時候,一個一個變量操作非常不便,此時我們可以使用一個數組集合,對整個數組集合進行遍歷或其他操作,最終實現批量的效果,數組使得我們的腳本更具擴展性。

1.3 變量與數組的差異

變量是存儲單個數據的單元,其在內存中是隨機存儲的,數組是存儲一系列數據的集合,是事先在內存中開辟連續的一系列空間,之后將數組元素有序的存儲在其中。

2. 數組的基本使用

2.1 數組的定義

數組的定義有兩種方式,可分為直接定義和單元素定義。

2.1.1 直接定義

數組類似于變量定義,只不過將里面的值用小括號括起來,其中每個元素使用空格分割。Shell 是弱類型的,數組中元素的類型可以不一樣,例如其中可以包含數字與字符串。

例如:

ARG1=(1 2 3 "hello Shell")

ARG1 為數組名稱,其值前三個為數字,最后一個為字符串。

2.1.2 單元素定義

Shell 中數組下標從 0 開始,利用單個元素來定義數組。

例如:

[root@master scripts]# ARG2[0]=1
[root@master scripts]# ARG2[1]=2
[root@master scripts]# ARG2[2]=3
[root@master scripts]# ARG2[3]="hello Shell" 

2.2 元素獲取

2.2.1 獲取單個元素

與變量的引用一樣,數組可以獲取單個位置的元素,利用 ${ARG[num]}。

例如:

[root@master scripts]# echo ${ARG1[0]}			//獲取AEG1數組中第一個元素
1
[root@master scripts]# echo ${ARG1[3]}			//獲取AEG1數組中第四個元素
hello Shell

2.2.2 獲取全部元素

  • 獲取數組值

獲取數組全部元素使用 ${ARG[*]}${ARG[@]}

例如:

[root@master scripts]# echo ${ARG1[@]}
1 2 3 hello Shell
[root@master scripts]# echo ${ARG1[*]}
1 2 3 hello Shell
  • 獲取數組下標

獲取數組全部下標使用 ${!ARG[*]}${!ARG[@]}。

例如:

[root@master ~]# echo ${!ARG1[@]}
0 1 2 3
[root@master ~]# echo ${!ARG1[*]}
0 1 2 3

2.2.3 獲取數組長度

  • 獲取整個數組長度

數組長度及數組中元素的個數,可以利用 ${#ARG[*]}${#ARG[@]},我們發現其實就是在獲取數組全部元素前添加#來獲取數組個數。

例如:

[root@master scripts]# echo ${#ARG1[*]}
4
[root@master scripts]# echo ${#ARG1[@]}
4
  • 獲取單個元素的長度

對于數組中的某個元我們也可以進行長度的獲取,可以利用 ${#ARG1[num]}。

例如:

[root@master scripts]# echo ${ARG1[@]} 
100 2 3 hello Shell 10
[root@master scripts]# echo ${ARG1[3]}		//獲取第四個元素內容為:hello Shell
hello Shell
[root@master scripts]# echo ${#ARG1[3]}		//獲取四個元素長度為11
11

2.2.4 數組元素的修改

數組可以進行一些列對其元素的操作。

  • 修改

對數組元素的修改,直接對單個元素修改即可,例如:

[root@master scripts]# AEG1[0]=100
[root@master scripts]# echo ${ARG1[@]}
100 2 3 hello Shell
  • 增加

對數組元素的增加,和修改一致,直接對單個位置元素增加即可,例如:

[root@master scripts]# ARG1[10]=10
[root@master scripts]# echo ${ARG1[@]}
100 2 3 hello Shell 10
[root@master scripts]# echo ${#ARG1[@]}
5

Tips:在此我們發現元素之前有 4 個元素,我們將下標 10 的元素賦值為 10,數組是按照從前往后順序賦值的。

  • 刪除

刪除數組可以使用 unset,unset ARG1[num] 可以刪除對應下標的數組元素,如果不帶下標則刪除數組的全部元素,例如:

[root@master scripts]# echo ${ARG1[@]} 
100 3 hello Shell 10
[root@master scripts]# unset ARG1[0]			//刪除下標為0的元素
[root@master scripts]# echo ${ARG1[@]}
3 hello Shell 10
[root@master scripts]# unset ARG1     		//刪除整個數組元素
[root@master scripts]# echo ${ARG1[@]}

2.2.5 數組的切片

和其他語言一樣,可以對數組進行切片也稱截取操作??梢酝ㄟ^ ${AEG1[@或*]:起始位置:長度} 對原數組進行切片,返回的為字符串,例如:

[root@master scripts]# echo ${ARG1[@]}
1 2 3 hello Shell
[root@master scripts]# echo ${ARG1[@]:0:2}				//從第1個元素往后2個元素進行切片
1 2

2.2.6 數組的替換

可以替換數組中的某一個元素,例如我們將 ARG1 數組中的第 1 個元素替換為 110。

[root@master scripts]# echo ${ARG1[@]}
1 2 3 hello Shell
[root@master scripts]# echo ${ARG1[@]/1/110}
110 2 3 hello Shell

3. Shell 數組分類

我們知道了 Shell 中數組的基本操作,來看一下數組的分類。

3.1 普通數組

普通數組就是我們上面以數字為下標的數組,上述的例子都為普通數組。

3.2 關聯數組

關聯數組是可以用字符串當作數組下標的一類數組,在使用關聯數組前,必須先使用 declare -A 聲明它,例如:

[root@master ~]# declare -A ARGFILE							//定義管理數組
[root@master ~]# ARGFILE=([name1]=Shell [name2]=linux [name3]=arg)		//關聯數組元素賦值
[root@master ~]# echo ${ARGFILE[@]}							//查看所有元素
arg linux Shell
[root@master ~]# echo ${ARGFILE[name1]}					//查看索引為name1的元素值
Shell

當然也可以對單個元素進行賦值操作, 我們可以看到關聯數組就沒有排序了,類似于其他語言中的字典,key 值也是字符串形式。

[root@master ~]# declare -A ARGLIST
[root@master ~]# ARGLIST[n1]=1
[root@master ~]# ARGLIST[n2]=2
[root@master ~]# ARGLIST[n3]="hello Shell" 
[root@master ~]# echo ${ARGLIST[@]}					//獲取關聯數組的所有值
2 hello Shell 1
[root@master ~]# echo ${#ARGLIST[@]}				//獲取關聯數組的元素個數
3
[root@master ~]# echo ${!ARGLIST[@]}				//獲取關聯數組的下標
n2 n3 n1

4. 實例

4.1 需求

我們想利用數組統計 linux 服務器的每 5 分鐘的網絡鏈接情況,查看處于各個時間段的服務器 TCP 鏈接的情況。

4.2 思路

可以利用 netstat -ant 命令來查看網絡鏈接情況,但是輸出的內容我們只關心最后一列的狀態,因此我們可以利用 awk 來打印從第二行開始到最后一列狀態,由于 awk 命令在后續我們會詳解,在此僅作為工具使用,例如:

[root@master ~]# netstat -ant|awk 'NR>2 {print $NF}'
LISTEN
LISTEN
ESTABLISHED
TIME_WAIT

打印出來的就是最后一列的狀態,我們將其內容作為數組的下標,值為其出現的次數,這樣就可以統計 TCP 鏈接到狀態,配合定時任務來定時統計服務器的 tcp 鏈接狀態。

4.3 實現

[root@master Shell_args]# cat tcp_status.sh 
#!/bin/bash
# Description: check tcp status
# Auth: kaliarch
# Email: [email protected]
# function: net check
# Date: 2020-03-14 14:00
# Version: 1.0

# 日志目錄
LOG_FILE="/tmp/tcp_status.log"

# 定義管理數組
declare -A TCP_STATUS

# 對數組進行內容賦值

# 利用netstat命令來過濾出關系的一列數據
for status in $(netstat -ant|awk 'NR>2 {print $NF}')
do
	# 對狀態相同狀態的TCP進行數值累加
	let TCP_STATUS[${status}]++
done

# 將統計完成的TCP鏈接狀態及數據記錄到日志中
for i in ${!TCP_STATUS[@]}
do 
	echo "$(date +%F" "%H:%m)  服務器的TCP狀態為: ${i} 的數量為: ${TCP_STATUS[${i}]}" >> ${LOG_FILE}
done


# 測試
[root@master ~]# bash tcp_status.sh 
[root@master ~]# cat /tmp/tcp_status.log 
2020-03-14 15:03  服務器的TCP狀態為: TIME_WAIT 的數量為: 138
2020-03-14 15:03  服務器的TCP狀態為: ESTABLISHED 的數量為: 501
2020-03-14 15:03  服務器的TCP狀態為: LISTEN 的數量為: 59

查看我們單獨運行腳本已經成功,可以將這個腳本加入 crontab 中,來定時執行,后期就可以通過日志來查看當時服務器的狀態了。

5. 注意事項

  • 需要在實戰中理解數組的具體用途,尤其注意關聯數組的靈活運用;
  • 需要理解數組的全部元素,元素下標以及元素的切片和替換,具體場景配合使用;
  • 數組一般用來統計批量的內容,例如批量文件的計算等,配合其他命令使用。

6. 小結

數組可謂為我們在 Shell 編程中提供了集合類型數據存儲的方案,對于批量數據的操作,數組功不可沒。在具體的實踐中根據數據特征,明確需求是利用數字作為下標的數組,還是使用關聯數組,最后在實踐中靈活運用數組的整體長度,切片,替換等操作,配合其他命令實現具體業務需求。