16、bash編程之數組介紹、及bash內置字符串處理工具介紹

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退出腳本。








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章