Bash編程之數組和字符串處理
目錄
筆記日期20180405
數組
聲名(創建)數組declare -a ARRAY_NAME
數組元素的賦值ARRAY_NAME=("VAL1" "VAL2" "VAL3"...)
引用數組元素:${ARRAY_NAME[INDEX]}
bash的字符串處理工具
字符串切片${var:offset:number}
基於模式取字串${var#*word}
查找替換變量的值${var/pattern/match}
查找並刪除變量的某些字符${var/#pattern}
字符大小寫轉換${var^^}
判斷變量賦值${var:-value}
創建臨時文件命令
mktemp
install
練習:寫一個腳本(復制命令以及其所依賴的庫)
變量:存儲單個元素的內存空間
數組:存儲多個元素的連續的內存空間
數組引用是從編號0開始,屬於數值索引
註意:索引也可以支持使用自定義的格式,而不僅僅是數值格式。
引用數組中的元素: ${ARRAY_NAME[INDEX]}
聲名(創建)數組:
declare -a ARRAY_NAME
declare -A ARRAY_NAME 關聯數組;
數組元素的賦值:
1. 一次只賦值一個元素
ARRAY_NAME[INDEX]=VALUE
例:weekdays[0]="Sunday"
weekdays[4]="Thursday"
2.一次賦值全部元素:
ARRAY_NAME=("VAL1" "VAL2" "VAL3"...)
可以使用命令替換來賦值如:testa=($(ls /))
然後使用此命令來查看此數組全部值 echo ${testa[*]}
3.只賦值特定元素
ARRAY_NAME=([0]="VAL1" [3]="VAL3" ...)
4.使用交互式賦值給數組
read -a ARRAY
每個元素之間加入空格
引用數組元素:${ARRAY_NAME[INDEX]}
註意:省略[INDEX]表示引用下標為0的元素
引用數組的長度(數組中元素的個數): ${#ARRAY_NAME[*]}, ${#ARRAY_NAME[@]}
示例: 生成10個隨機數存入數組,並找出其最小值
#!/bin/bash
#
declare -a rand
declare -i MiNum=0
for i in {1..10}; do
rand[$[$i-1]]=$RANDOM
echo ${rand[$[$i-1]]}
[ $MiNum -eq 0 ] && MiNum=${rand[$[$i-1]]}
[ ${rand[$[$i-1]]} -lt $MiNum ] && MiNum=${rand[$[$i-1]]}
done
echo "Min: $MiNum"
所有元素 ${ARRAY_NAME[*]} ${ARRAY_NAME[@]}
數組切片 ${ARRAY[@]:offset:number}
offset: 要跳過的元素個數
number: 要取出的元素的個數,取偏移量之後的所有元素: ${ARRAY[@]:offset}
向數組中追加元素 ARRAY[${#ARRAY[*]}]
刪除數組中的某元素 unset ARRAY[INDEX]
bash的字符串處理工具
字符串切片:
${var:offset:number}
取出字符串的最右側幾個字符:${var: -lengh}
註意:冒號後必須有一個空白字符
如:chart=Balish
echo ${chart:offset:2}
Ba
echo ${chart: -2}
sh
基於模式取字串
${var#*word} 其中word可以是指定的任意字符
功能:自左向右,查找var變量所存儲的字符串中,第一次出現word字符,並從左向右
刪除字符至第一次出現word字符處(註意:word字符也會被刪除)
# chart=Bllllish
# echo ${chart#*l}
lllish
${var##*word}
功能:自左向右,查找var變量所存儲的字符串中,最後次出現word字符,並從左向右
刪除字符至最後一次出現word字符處(註意:word字符也會被刪除)
# chart=Bllllish
# echo ${chart##*l}
ish
${var%word*}
功能:自右向左,查找var變量所存儲的字符串中,第一次出現word字符,並從右向左
刪除字符至第一次出現word字符處(註意:word字符也會被刪除)
# char="/var/log/message"
# echo "${char%/*}"
/var/log
${var%word*}
功能:自右向左,查找var變量所存儲的字符串中,最後一次出現word字符,並從右向左
刪除字符至第一次出現word字符處(註意:word字符也會被刪除)
# char="/var/log/messssssssage"
# echo "${char%%s*}"
/var/log/me
查找替換變量的值
可以將變量中被查找到的字符串用其它字符串替換
${var/pattern/match}
功能:查找var變量中第一次被pattern匹配到的字符,並用match來替換其字符
# char="Linuuuuuuuuux Machine"
# echo "${char/u/U}"
LinUuuuuuuuux Machine
${var//pattern/match}
功能:查找var變量中所有被pattern匹配到的字符,並用match來替換其字符
# char="Linnnnnnnnnnx Machinnnnnnne"
# echo "${char//n/N}"
LiNNNNNNNNNNx MachiNNNNNNNe
${var/#pattern/match}
功能:查找var變量中行首為pattern匹配到的字符,並用match來替換其字符
# char="root:admin:123:root"
# echo "${char/#root/ROOT}"
ROOT:admin:123:root
${var/%pattern/match}
功能:查找var變量中行尾為pattern匹配到的字符,並用match來替換其字符
# char="root:admin:123:root"
# echo "${char/%root/ROOT}"
root:admin:123:ROOT
查找並刪除變量的某些字符
可以刪除變量中被查找到的字符串
這裏不再做示例與上邊的查找替換非常相似,只是後邊不指定替換,就會將查找到的刪除
${var/pattern} 自左向右查找變量中第一次被pattern匹配到的字符,並刪除
${var//pattern} 自左向右查找變量中所有被pattern匹配到的字符,並刪除
${var/#pattern} 查找變量中行首被pattern匹配到的字符,並刪除
${var/%pattern} 查找變量中行尾被pattern匹配到的字符,並刪除
字符大小寫轉換
可以將變量中的字符做大小寫轉換
${var^^} 將變量中所有的小寫字符轉換為大寫
${var,,} 將變量中所有的大寫字符轉換為小寫
# char="root:x:0:0:root:/root:/bin/bash"
# echo ${char^^}
ROOT:X:0:0:ROOT:/ROOT:/BIN/BASH
判斷變量賦值
判斷變量,如果變量有值做何操作,沒有值做何操作
${var:-value} 如果變量有值則顯示變量的值,如果沒有則顯示value字符
${var:=value} 如果變量有值則顯示變量的值,如果沒有值則會將value賦值給變量var
並顯示value
${var:+value} 與-符號相反,var變量有值則返回value。
${var:?error_info} 如果var為空或未設置,則返回error_info,否則返回var的值
[root@mydomain ~]# unset char
[root@mydomain ~]# echo $char
[root@mydomain ~]# echo ${char:=animal}
animal
[root@mydomain ~]#
為腳本程序使用配置文件
1.定義文本文件,每行"key=value"
2.在腳本中source此文件即可
創建臨時文件命令
mktemp - create a temporary file or directory
mktemp [OPTION]... [TEMPLATE]
-d, --directory
create a directory, not a file
-p DIR, --tmpdir[=DIR]
指明臨時文件目錄位置
mktemp /tmp/name_file.XXXX
此命令創建文件後邊的X會隨機變換一個字符,這樣可以使創建的文件不會沖突
或者重復導致無法創建文件
install - copy files and set attributes
install [OPTION]... [-T] SOURCE DEST
install [OPTION]... SOURCE... DIRECTORY
install [OPTION]... -t DIRECTORY SOURCE...
install [OPTION]... -d DIRECTORY...
options
-g group
-m mode
-o owner
install命令有make命令所沒有的功能就是他可以指定復制的文件或者創建的目錄的屬組,
權限,屬主
練習:寫一個腳本(復制命令以及其所依賴的庫)
1. 提示用戶輸入一個可執行的命令名稱
2. 獲取此命令所依賴到的庫文件列表
3. 復制命令至目標目錄(例如/mnt/sysroot)下對應的路徑下
/bin/bash ==> /mnt/sysroot/bin/bash
/usr/bin/passwd ==> /mnt/sysroot/usr/bin/passwd
4. 復制此命令依賴到的所有庫文件至目標目錄下的對應路徑下
/lib64/ld-linux-x86-64.so.2 ==> /mnt/sysroot/lib64/ld-linux-x86-64.so.2
5. 每次復制完成一個命令後,不要退出,而是提示用戶鍵入新的要復制的命令,並重復完成
上述功能,直到用戶輸入quit退出腳本
答案:表示用時3小時,真心的慢哈哈,
如果想復制使用,註意版面,有可能有的是一行內容被拆成兩行了
#!/bin/bash
#
#Description: This script can copy the commands that you have gaven,
#and the library which the command depended on.
maindir="/mnt/sysroot"
cmd=notquit
copycmd () {
cmddir=${cmd%/*}/
[ -d $maindir$cmddir ] || mkdir -pv $maindir$cmddir
[ -x $maindir$cmd ] && echo "The {${1##*/}} command has existed in $maindir$cmddir." || cp --preserve $cmd $maindir$cmddir
}
function cplib {
for I in $(ldd $cmd | grep -o "/.*[[:space:]]"); do
[ -d $maindir${I%/*} ] || mkdir -pv $maindir${I%/*}
[ -e $maindir$I ] || cp --preserve $I $maindir$I
done
}
while [ ! $cmd == "quit" ]; do
read -p "Input CMD:" cmd
while [ -z $cmd ]; do
read -p "Please input something:" cmd
done
[ $cmd == "quit" ] && break
if $(which $cmd &> /dev/null); then
cmd=$(which $cmd)
copycmd $cmd
cplib $cmd
else
echo "($cmd) is not a Linux's command"
fi
done
Bash編程之數組和字符串處理