1、程序構成:
主要由指令和數據構成,數據可以是變量、文件、數組
2、數組介紹:
變量:存儲單個元素的內存空間
數組:存儲多個元素的連續的內存空間
3、數組的特點:
數組名:整個數組只有一個名字
數組索引:元素編號從“0”開始,數組名[索引]
注意:對於bash-4及之後的版本,支持自定義的索引格式,而不僅僅是0,1,2....等等數字格式。同時數組可以不事先聲明,可以直接使用,但是如果不聲明,它會把多個字符串的變量當做一個變量,因此使用數組前,應先聲明數組。
4、聲明數組:(有兩種方式)
方式一:declare -a NAME //聲明索引數組,用0,1,2,3....表示各元素
方式二:declare -A NAME //聲明關聯數組,自定義索引格式
5、給數組中元素賦值:
賦值方式 | 備註 |
①、一次只賦值一個元素: 格式:ARRAY_NAME[INDEX]=value 示例: [root@localhost ~]# declare -a animal [root@localhost ~]# animal[0]=pig [root@localhost ~]# animal[1]=sheep [root@localhost ~]# echo $animal //引用第“0”個元素 pig [root@localhost ~]# echo ${animal[1]} pig[1] [root@localhost ~]# | |
②、一次賦值全部元素: 格式:ARRAY_NAME=("VALUE1" "VALUE2" "VALUE3" ...) //必須以空格鍵隔開各元素值 示例: [root@localhost ~]# weekdays=("monday" "tuesday" "wedsday") [root@localhost ~]# echo ${weekdays[2]} wedsday [root@localhost ~]# | |
③、只賦值特定元素: 格式:ARRAY_NAME=([0]="VAL0" [1]="VAL1" [3]="VAL3") //可以不連續賦值,此種被稱爲稀疏數組。 示例: [root@localhost ~]# cigrate=([0]="najing" [1]="xiaosu" [4]="yuxi") [root@localhost ~]# echo ${cigrate[0]} najing [root@localhost ~]# echo ${cigrate[1]} xiaosu [root@localhost ~]# echo ${cigrate[2]} [root@localhost ~]# echo ${cigrate[3]} [root@localhost ~]# echo ${cigrate[4]} yuxi [root@localhost ~]# 注意:bash支持稀疏格式的數組。 | |
④、read -a ARRAY_NAME //回車後輸入輸入元素 示例: [root@localhost ~]# read -a ARR_name jiangsu anhui hubei [root@localhost ~]# echo $ARR_name jiangsu [root@localhost ~]# | |
⑤、關聯數組: ARRAY_NAME[INDEX]=var //必須declare -A後才能使用關聯數組 示例: [root@localhost ~]# declare -A world [root@localhost ~]# world[zh]=china [root@localhost ~]# world[en]=english [root@localhost ~]# echo $world [root@localhost ~]# echo $world[zh] [zh] [root@localhost ~]# echo $world[en] [en] [root@localhost ~]# |
6、數組元素引用:
格式: ${ARRAY_NAME[INDEX]} //必須加{ },因爲不加,則只會引用ARRAY_NAME,而不是整個數組元素。
數組元素其他使用技巧:
①、數組元素的長度:(數組元素的個數) 格式一:${#ARRAY_NAME[*]} //如果不加*或@表示引用數組中的第一個元素的個數 格式二:${#ARRAY_NAME[@]} //如果不加*或@表示引用數組中的第一個元素的個數 示例: [root@localhost ~]# declare -a china //聲明一個數組名爲china [root@localhost ~]# china=("bejing" "hanghai" "guanzhou" "jiangsu") //給數組賦值 [root@localhost ~]# echo $china //此種將會輸出數組中的第一個元素值 bejing [root@localhost ~]# echo ${#china[*]} //輸出數組中元素的個數,即數組長度 4 [root@localhost ~]# echo ${#china[@]} //輸出數組中元素的個數,即數組長度 4 [root@localhost ~]# echo ${#china} //若不加“*”或“@”,則表示輸出數組中第一個元素字符的個數 6 [root@localhost ~]# | |
②、數組中第一個元素的字符個數: 格式:${#ARRAY_NAME} 示例: [root@localhost ~]# declare -a china [root@localhost ~]# china=("bejing" "hanghai" "guanzhou" "jiangsu") [root@localhost ~]# echo ${#china} 6 | |
③、引用或查看數組中的全部元素值 格式一:${ARRAY_NAME[*]} 格式二:${ARRAY_NAME[@]} [root@localhost ~]# declare -a china [root@localhost ~]# china=("bejing" "hanghai" "guanzhou" "jiangsu") [root@localhost ~]# echo ${chian[*]} bejing hanghai guanzhou jiangsu [root@localhost ~]# echo ${chian[@]} bejing hanghai guanzhou jiangsu [root@localhost ~]# | |
④、數組元素切片 格式一:${ARRAY_NAME[@]:offset:number} 格式二:${ARRAY_NAME[*]:offset:number} offset:要略過的元素的個數,即偏移量,注意此處不是步長的概念。 number:要取出元素的個數,省略number時表示取偏移量之後的所有元素 示例: [root@localhost sh]# declare -a files [root@localhost sh]# files=(/etc/[Pp]*) [root@localhost sh]# echo ${files[@]} /etc/PackageKit /etc/pam.d /etc/pam_pkcs11 /etc/passwd /etc/passwd- /etc/pbm2ppa.conf /etc/pcp /etc/pcp.conf /etc/pcp.env /etc/Pegasus /etc/pinforc /etc/pkcs11 /etc/pki /etc/plymouth /etc/pm /etc/pnm2ppa.conf /etc/polkit-1 /etc/popt.d /etc/portreserve /etc/postfix /etc/ppp /etc/prelink.conf.d /etc/printcap /etc/profile /etc/profile.d /etc/protocols /etc/pulse /etc/purple /etc/python [root@localhost sh]# echo ${files[@]:2:2} /etc/pam_pkcs11 /etc/passwd [root@localhost sh]# echo ${files[*]:2:2} /etc/pam_pkcs11 /etc/passwd [root@localhost sh]# [root@localhost sh]# echo ${files[*]:10} /etc/pinforc /etc/pkcs11 /etc/pki /etc/plymouth /etc/pm /etc/pnm2ppa.conf /etc/polkit-1 /etc/popt.d /etc/portreserve /etc/postfix /etc/ppp /etc/prelink.conf.d /etc/printcap /etc/profile /etc/profile.d /etc/protocols /etc/pulse /etc/purple /etc/python [root@localhost sh]# | |
⑤、向數組中追加元素(非稀疏格式) 格式一:ARRAY_NAME[{#ARRAY_NAME[@]}]=value //標紅部分表示數組長度,即要追加元素的下標 格式二:ARRAY_NAME[{#ARRAY_NAME[*]}]=value //標紅部分表示數組長度,即要追加元素的下標 | |
⑥、刪除數組中的某元素 撤銷變量:#unset VAR //VAR是變量名 撤銷數組中的某元素:#unset ARRAY[INDEX] //注意:不要加“$”因爲撤銷的是元素 |
7、數組練習示例:
①、生成10個隨機數,並找出其中的最大值和最小值。
[root@localhost sh]# cat array_max_min.sh
#!/bin/bash
declare -i max=0
declare -i min=0
declare -a array_int
for i in `seq 1 10` ;do
array_int[$i]=$RANDOM
echo ${array_int[$i]}
if [ $i -eq 1 ]; then
max=${array_int[$i]}
min=${array_int[$i]}
elif [ ${array_int[$i]} -gt $max ];then
max=${array_int[$i]}
elif [ ${array_int[$i]} -lt $min ];then
min=${array_int[$i]}
fi
done
echo "max=$max ; min=$min"
[root@localhost sh]#
②、生成10個隨機數字,而後進行由小到大進程排序。
③、寫一個腳本實現如下功能
定義一個數組,數組中的元素是/var/log目錄下所有以".log"結尾的文件,統計其下標爲偶數的文件的行數之和。
[root@localhost sh]# cat array_pattern.sh
#!/bin/bash
declare -a files
files=(/var/log/*.log)
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"
[root@localhost sh]#
8、bash內置字符串處理:
8.1字符串切片: 格式:${var:offset:number} //var是變量名,offset是偏移量,number是取出的個數,整個意思是:取字符串的子串, 示例: [root@localhost ~]# name=changcheng [root@localhost ~]# echo ${name} changcheng [root@localhost ~]# echo ${name:2} //取偏移量之後所有字符 angcheng [root@localhost ~]# echo ${name:2:3} //取偏移量之後的3個字符 ang [root@localhost ~]# |
8.2、基於模式取子串: 格式一:${var#*word} //其中word是指定的分隔符,整個表達式的功能是:自左向右查找var變量所存儲的字符串中,第一次出現的word分隔符,刪除字符串開頭至此分隔符之間的所有字符。 示例: [root@localhost ~]# echo ${name} changcheng [root@localhost ~]# echo ${name#*ang} cheng [root@localhost ~]# 格式二:${var##*word} //其中word是指定的分隔符,整個表達式的功能是:自左向右,查找var變量所存儲的字符串中,最後一次出現的word分隔符,刪除字符串開頭至此分隔符之間的所有字符。 示例: [root@localhost ~]# mypath="/etc/init.d/functions" [root@localhost ~]# echo ${mypath} /etc/init.d/functions [root@localhost ~]# echo ${mypath#*/} etc/init.d/functions [root@localhost ~]# echo ${mypath##*/} //取路徑基名 functions [root@localhost ~]# 格式三:${var%word*} //其中word是指定的分隔符,功能是:自右向左,查找var變量所存儲的字符串中,第一次出現的word分隔符,刪除此分隔符至字符串結尾部分之間的所有字符。 示例: [root@localhost ~]# mypath="/etc/init.d/functions" [root@localhost ~]# echo ${mypath} /etc/init.d/functions [root@localhost ~]# echo ${mypath%/*} //取路徑名 /etc/init.d [root@localhost ~]# 格式四:${var%%word*} //其中word是指定的分隔符,功能是:自右向左,查找var變量所存儲的字符串中,最後一次出現的word分隔符,刪除此分隔符至字符串結尾部分之間的所有字符。 示例: [root@localhost ~]# mypath="/etc/init.d/functions" [root@localhost ~]# echo ${mypath} /etc/init.d/functions [root@localhost ~]# echo ${mypath%%/*} [root@localhost ~]# [root@localhost ~]# myurl=http://www.magedu.com:80 [root@localhost ~]# echo ${myurl##*:} //取端口號 80 [root@localhost ~]# echo ${myurl%%:*} //取協議號 http [root@localhost ~]# |
8.3:、字符串查找和替換: 格式一:${var/PATTERN/SUBSTI} //查找var表示的字符串中,第一次被PATTERN所匹配的字符串,將其替換爲SUBSTI所表示的字符串。 格式二:${var//PARTTERN/SUBSTI} //查找var表示的字符串中,所有被PATTERN所匹配的字符串,全部將其替換爲SUBSTI所表示的字符串。 格式三:${var/#PATTERN/SUBSTI} //查找var表示的字符串中,行首被PATTERN所匹配的字符串,將其替換爲SUBSTI所表示的字符串;注意:僅行首被匹配時才做替換。 格式四:${var/%PATTERN/SUBSTI} //查找var表示的字符串中,行尾被PATTERN所匹配的字符串,將其替換爲SUBSTI所表示的字符串;注意:僅行尾被匹配時才做替換。 注意:此處的PATTERN僅適用glob風格的通配模式。 示例: [root@localhost ~]# userinfo=`head -1 /etc/passwd` [root@localhost ~]# echo ${userinfo} root:x:0:0:root:/root:/bin/bash [root@localhost ~]# echo ${userinfo/root/user} user:x:0:0:root:/root:/bin/bash [root@localhost ~]# echo ${userinfo//root/user} user:x:0:0:user:/user:/bin/bash [root@localhost ~]# echo ${userinfo/#oot/mage} root:x:0:0:root:/root:/bin/bash [root@localhost ~]# echo ${userinfo/#roo/mage} maget:x:0:0:root:/root:/bin/bash [root@localhost ~]# echo ${userinfo/%roo/mage} root:x:0:0:root:/root:/bin/bash [root@localhost ~]# echo ${userinfo/%bas/mage} root:x:0:0:root:/root:/bin/bash [root@localhost ~]# echo ${userinfo/%bash/mage} root:x:0:0:root:/root:/bin/mage [root@localhost ~]# |
8.4、字符串的查找刪除: 格式一:${var/PATTERN} //以PATTERN爲模式,查找var字符串中第一次的匹配,並刪除。 格式二:${var//PATTERN} //以PATTERN爲模式,查找var字符串中所有匹配的字符串,並刪除。 格式三:${var/#PATTERN} //以PATTERN爲模式,查找var字符串中僅行首匹配到的字符串,並刪除。 格式四:${var/%PATTERN} //以PATTERN爲模式,查找var字符串中僅行尾匹配的字符串,並刪除。 示例: [root@localhost ~]# userinfo=$(head -1 /etc/passwd) [root@localhost ~]# echo ${userinfo} root:x:0:0:root:/root:/bin/bash [root@localhost ~]# echo ${userinfo/root} :x:0:0:root:/root:/bin/bash [root@localhost ~]# echo ${userinfo//root} :x:0:0::/:/bin/bash [root@localhost ~]# echo ${userinfo/#root} :x:0:0:root:/root:/bin/bash [root@localhost ~]# echo ${userinfo/%root} root:x:0:0:root:/root:/bin/bash [root@localhost ~]# echo ${userinfo/%bash} root:x:0:0:root:/root:/bin/ [root@localhost ~]# |
8.5、字符串大小寫轉換: 格式一:${var^^} //把var中所有小寫字符轉成大寫字符 格式二:${var,,} //把var中所有大寫字符轉成小寫字符 示例: [root@localhost ~]# userinfo=$(head -1 /etc/passwd) [root@localhost ~]# echo ${userinfo} root:x:0:0:root:/root:/bin/bash [root@localhost ~]# echo ${userinfo^^} ROOT:X:0:0:ROOT:/ROOT:/BIN/BASH [root@localhost ~]# [root@localhost ~]# say="ILoveU" [root@localhost ~]# echo ${say} ILoveU [root@localhost ~]# echo ${say,,} iloveu [root@localhost ~]# |
8.6、變量賦值: 格式一:${var:-VALUE} //var是變量;表示如果var變量爲空,或者未設置,那麼返回VALUE,否則返回var變量的值。 格式二:${var:=VALUE} //var是變量;表示如果var變量爲空,或者未設置,那麼返回VALUE,並將VALUE賦值給var變量,否則返回var變量的值。 格式三:${var:+VALUE} //如果var變量不爲空,則返回VALUE值。 格式四:${var:?ERROR_INFO} //如果var爲空,或者未設置,那麼返回ERROR_INFO爲錯誤提示,否則,返回var值。 示例: [root@localhost ~]# echo ${xuexiao} [root@localhost ~]# echo ${xuexiao:-nanda} nanda [root@localhost ~]# echo ${xuexiao:=nanda} nanda [root@localhost ~]# echo ${xuexiao} nanda [root@localhost ~]# echo ${xuexiao:+beida} beida [root@localhost ~]# echo ${xuexiao:?buzhidao} nanda [root@localhost ~]# echo ${xuexiao1:?buzhidao} bash: xuexiao1: buzhidao [root@localhost ~]# |
9、練習:寫一個腳本,實現如下功能:
①、提示用戶輸入一個可執行命令的名稱:
②、獲取此命令所依賴的所有的庫文件列表(ldd),把此目錄當根
③、複製命令至某目標文件(例如:/mnt/sysroot)下的對應路徑中,
例如:bash,/bin/bash ==>/mnt/sysroot/bin/bash
④、複製此命令依賴到的所有庫文件至目標目錄下的對應路徑下:
例如:/lib64/ld-linux-x86_64.so.2 ==>/mnt/sysroot//lib64/ld-linux-x86_64.so.2
⑤、每次複製完成一個命令後,不要退出,而是提示用戶繼續輸入要複製的其他命令,並重復完成如上述所描述的功能,直到用戶輸入quit退出腳本。