bash shell(3) 陣列 排序
阿新 • • 發佈:2019-01-23
8月16日內容
(一)bash程式設計權威指南10
前言:程式=指令+資料 或 程式=程式碼+資料 。
指令:整個語法關鍵字、系統命令、自定義函式
資料:變數,檔案,陣列
變數:儲存單個元素的記憶體中的一塊儲存空間
陣列:儲存多個元素的記憶體中的連續的記憶體空間 ,陣列有陣列名,且索引編號從0開始。
資料結構中邏輯結構:集合、線性、樹形、圖形
資料結構中物理結構(也叫做儲存結構):順序、鏈式、索引、雜湊
bash shell 中的陣列屬於線性表,體現為所有元素的記憶體地址是連續的
- 宣告一個數組
declare -a NAME:宣告索引陣列(索引是數值)
declare -A NAME:宣告關聯陣列(索引是字串)
- 陣列中元素的賦值方式
- (1)一次只賦值一個元素
- arr[0]=hello
- (2)一次賦值全部元素
- arr=(“hello” “nihao” “who” )
- (3)只賦值特定元素
- arr=([0]=”nihao” [3]=”hello”)
- 注意:bash支援稀疏格式的陣列
- (4)read -a arr
- (1)一次只賦值一個元素
- 引用陣列中元素的方式:通過索引取值
- ${arr[1]}
陣列中元素的索引是從0開始的,${arr[1]}表示取的是第二個元素的值
- 注意:引用時,只給陣列名,表示引用下標為0的元素。例如:
$arr == ${arr[0]}
- 獲取陣列的長度(陣列中元素的個數)
${#arr[*]}
${#arr[@]}
- 獲取陣列中的全部元素
${arr[*]}
${arr[@]}
- 示例:生成10個隨機數,並找出其中的最大值和最小值
#!/bin/bash
#
declare -a rand
declare -i max=0
declare -i min=1000000
for i in {0..9}; do
rand[$i]=$RANDOM # $RANDOM的值是一個隨機數
echo ${rand[$i]}
[ ${rand[$i]} -gt $max ] && max=${rand[$i]}
[ ${rand[$i]} -lt $min ] && min=${rand[$i]}
done
echo "The MAX number is $max "
echo "The MIN number is $min"
練習:生成10個隨機數,而後由小到大進行排序(排序演算法的思想一定要掌握)
氣泡排序演算法演示(對於迴圈語句的選取不限為while迴圈或for迴圈)
#!/bin/bash
#
declare -a rand
declare -i rand_length
declare -i var
# 生成10個隨機數
for i in {0..9}; do
rand[$i]=$[ $RANDOM%100 ] # $RANDOM的值是一個隨機數
done
echo ${rand[*]}
rand_length=${#rand[*]}
# echo $rand_length
# 開始寫氣泡排序
for i in `seq 0 $[ $rand_length-1 ] | sort -n -r`;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 "\E[1;31m${rand[*]} \033[0m"
- 練習:寫一個指令碼,定義一個數組,陣列中的元素是/var/log/目錄下所有的以.log結尾的檔名,統計其下標為偶數的檔案中的行數之和
#!/bin/bash
#
declare -a files
files=(/var/log/*.log)
declare -i lines=0
for i in $(seq 0 $[${#files[*]}-1]); do
if [ $[$i%2] -eq 0 ]; then
let lines+=$(wc -l ${files[$i]} | cut -d' ' -f1)
fi
done
echo "Lines: $lines."
- 陣列的其他功能
- 陣列元素切片
- 例如:${file[*]:2:3}:表示在顯示file中的全部元素的時候,跳過前
兩個元素
,顯示後面三個元素
- 例如:${file[*]:2:3}:表示在顯示file中的全部元素的時候,跳過前
- 向非稀疏格式的陣列中追加元素
- 例如:arr[${#arr[*]}]=hello
- 刪除陣列中的某個元素
- 例如:unset arr[2]
- 關聯陣列的賦值
- 例如:declare -A arr(注意關聯陣列需要首先宣告), arr=([a]=”nihao” [b]=”nima” [c]=”nidaye”)
- 陣列元素切片
- bash的內建字串處理工具(瞭解)
字串切片,對於變數而言
- 例如:name=nihaoma , echo ${name:2:3} 列印的結果為:hao
- 例如:name=nihaoma , echo ${name: -4} 列印的結果為:aoma
基於模式取字串,對於變數而言
- ${var#*word}:其中word是指定的分隔符。功能:自左向右,查詢var變數所儲存的字串中,第一次出現的word分隔符,刪除字串開頭至此分隔符處的所有字元
例如:path="/var/log/yhy.txt" , echo ${path#*/} 列印結果為:var/log/yhy.txt
- ${var##*word}:其中word是指定的分隔符。功能:自左向右,查詢var變數所儲存的字串中,最後一次出現的word分隔符,刪除字串開頭至此分隔符處的所有字元
例如:path="/var/log/yhy.txt" , echo ${path##*/} 列印結果為:yhy.txt
- ${var%word*}:其中word是指定的分隔符。功能:自右向左,查詢var變數所儲存的字串中,第一次出現的word分隔符,刪除字串結尾至此分隔符處的所有字元
例如:path="/var/log/yhy.txt" , echo ${path%/*} 列印結果為:/var/log
- ${var%%word*}:其中word是指定的分隔符。功能:自右向左,查詢var變數所儲存的字串中,最後一次出現的word分隔符,刪除字串結尾至此分隔符處的所有字元
例如:path="/var/log/yhy.txt" , echo ${path%%/*} 列印結果為:空
- ${var#*word}:其中word是指定的分隔符。功能:自左向右,查詢var變數所儲存的字串中,第一次出現的word分隔符,刪除字串開頭至此分隔符處的所有字元
- 查詢替換
- ${var/pattern/substi}:查詢var所表示的字串,第一次被pattern所匹配到的字串,將其替換為substi所表示的字串
- ${var//pattern/substi}:查詢var所表示的字串,所有被pattern所匹配到的字串,將其所有匹配到的字串替換為substi所表示的字串
- ${var/#pattern/substi}:查詢var所表示的字串,行首被pattern所匹配到的字串,將其替換為substi所表示的字串,如果不是行首,就不替換
- ${var/%pattern/substi}:查詢var所表示的字串,行尾被pattern所匹配到的字串,將其替換為substi所表示的字串,如果不是行尾,就不替換
-查詢刪除 - ${var/pattern}:查詢var所表示的字串,第一次被pattern所匹配到的字串刪除
- ${var//pattern}:查詢var所表示的字串,所有被pattern所匹配到的字串刪除
- ${var/#pattern}:查詢var所表示的字串,行首被pattern所匹配到的字串刪除
- ${var/%pattern}:查詢var所表示的字串,行尾被pattern所匹配到的字串刪除
- 字元大小寫轉換
- ${var^^}:把var中的所有小寫轉換為大寫
- ${var,,}:把var中的所有大寫轉換為小寫
- 變數賦值
- ${var:-VALUE}: 如果var變數為空,或未設定那麼返回VALUE,否則返回var變數的值
- ${var:=VALUE}: 如果var變數為空,或未設定那麼返回VALUE,並將VALUE賦值給var變數,否則返回var變數的值
- ${var:+VALUE}: 如果var變數不空,那麼返回VALUE
- ${var:?ERROR_INFO}: 如果var為空,或未設定,那麼返回ERROR_INFO為錯誤提示,否則,返回var的值
- 綜合練習1:ping命令去檢視192.168.10.1—192.168.10.10 範圍內的所有主機是否線上,線上顯示為up,不線上顯示為down,分別統計線上主機,及不線上主機數量
#!/bin/bash
#
declare -i uphosts=0
declare -i downhosts=0
declare -i i=1
hostping() {
if ping -W 1 -c 1 $1 &> /dev/null; then
echo "$1 is up."
let uphosts+=1
else
echo "$1 is down."
let downhosts+=1
fi
}
while [ $i -le 67 ]; do
hostping 172.16.$i.1
let i++
done
echo "Up hosts: $uphosts, Down hosts: $downhosts."
- 綜合練習2:寫一個指令碼:能探測C類,B類,A類網路中所有的主機是否線上,以192開頭的主機
#!/bin/bash
#
cping() {
local i=1
# 為了看到效果,這裡的255可以寫成5
while [ $i -le 5 ]; do
if ping -W 1 -c 1 $1.$i &> /dev/null; then
echo "$1.$i is up"
else
echo "$1.$i is down."
fi
let i++
done
}
bping() {
local j=0
# 為了看到效果,這裡的255可以寫成5
while [ $j -le 5 ]; do
cping $1.$j
let j++
done
}
aping() {
local x=0
while [ $x -le 255 ]; do
bping $1.$x
let x++
done
}
aping 192