標籤:shell 數組 declare eval
數組ARRAY
變數:儲存單個元素的記憶體空間
數組:儲存多個元素的連續的記憶體空間,相當於多個變數的集合,元素編號支援稀疏格式,即索引編號不連續。
進階變數用法 - 有類型變數
Shell變數一般是無類型的,但是bash提供了declare和typeset兩個命令用於指定變數的類型,兩個命令是等價的
declare [OPTION] 變數名
-r 聲明或顯示唯讀變數
-i 聲明或顯示整數型變數
-a 聲明或顯示索引數組
-A 聲明或顯示關聯陣列
-f 顯示系統的所有函數
-F 僅顯示所有函數名
-x 聲明或顯示環境變數和函數
-l 聲明變數為小寫字母 declare –l var=UPPER
-u 聲明變數為大寫字母 declare –u var=lower
聲明數組:
declare -a ARRAY_NAME //聲明索引數組,元素編號只能是數字,從0開始
declare -A ARRAY_NAME //聲明關聯陣列,元素編號可以自訂格式,需bash4.0以上的版本才支援
declare -i ARRAY_NAME //聲明整數數組,元素變數只支援整數值
declare -r ARRAY_NAME //聲明唯讀數組
declare -l ARRAY_NAME //轉換數組為小寫
declare -u ARRAY_NAME //轉換數組為大寫
聲明數組
declare -a user //聲明索引數組
declare -a //查看索引數組
declare -A user //聲明關聯陣列
declare -A
declare -i //查看所有整數數組
數組元素賦值,索引數組的編號只支援數字,而且是從0開始
1.單個元素賦值
user[0]="user0"
user[1]="user1"
user[2]="user2"
user[3]="user3"
user[4]="user4"
user[5]="user5"
2.多個元素賦值
user=("usera" "userb" "userc" "userd" ...)
3.只賦值特定元素,則其他未賦值的元素值為空白,如user[1]就為空白
user=([0]="usera" [3]="userc"...)
4.互動式賦值
read -a user
a b c d e //輸入的參數以空格隔開
a\ b cc ee //如果輸入的參數包含空格則需要轉義,如"a b".
顯示或引用數組
declare -a
echo $user //顯示第一個元素,相當於echo ${user[0]}
echo ${user[0]}
echo ${user[2]}
echo ${user[3]}
echo ${user[*]}
echo ${#user[*]}
取消數組或元素
unset user[2] //取消數組元素2
unset user //取消整個數組
聲明關聯陣列
declare -A user
數組元素賦值,編號支援字母,數字或單詞
user[a]=usera
user[b]=userb
user[2]=userc
user[abc]=userabc
查看數組元素值
declare -A|tail -1
echo ${user[a]}
echo ${user[2]}
echo ${user[abc]}
取消數組或元素
unset user[a]
unset user
批量定義數組元素,未聲明數群組類型則預設為索引數組
user=(usera userb userc userd)
echo ${user[3]}
num=({1..10})
echo ${num[8]}
echo ${num[*]} //顯示數組中的所有元素,*也可用@代替
echo ${#num[*]} //顯示數組的元素個數,*也可用@代替
file=({/app/bin/*.sh})
echo ${file[3]}
echo ${file[@]} //顯示數組的所有元素
echo ${#file[@]} //顯示數組的元素個數
num=({1..10})
for((i=0;i<${#num[@]};i++));do echo num is ${num[$i]};done
unset num[2]
for((i=0;i<${#num[@]};i++));do echo num is ${num[$i]};done //稀疏數組顯示會有問題,即不會自動遞迴填補空值
num[2]=3 //添加缺少的數組元素
數組元素處理
數組切片:${ARRAY[@]:offset:number}
offset: 要跳過的元素個數
number: 要取出的元素個數
num=({1..10})
echo ${num[*]:2:5} //跳過前2個,取出5個元素
3 4 5 6 7
echo ${num[*]:3} //跳過前3個,取出之後的所有元素
4 5 6 7 8 9 10 11 12 13
seq 10 //顯示1..10,預設從1開始到指定數字
seq 2 5 //顯示2,3,4,5,顯示從起始值到結束值之間的數字
seq 1 2 10 //顯示1,3,5,7,9,格式為起始值,增量值,結束值
num=10;seq 0 2 $[$num-1]
echo {1..10..2} //顯示1,3,5,7,9,格式為起始值,結束值,增量值
num=({1..10..2})
向數組中追加元素:ARRAY[${#ARRAY[*]}]
num=({1..10})
echo ${sum[10]} 值為空白
num[${#num[*]}]=11 //追加數組元素,追加到所有數組元素的最後
echo ${sum[10]} 顯示追加的元素值11
num[${#num[*]}]=12 //可追加多次
num[${#num[*]}]=13
刪除數組中的某元素,會導致稀疏格式:unset ARRAY[INDEX]
unset num[8]
刪除整個數組:unset ARRAY
unset num
字串處理
man bash 搜尋\$\{parameter\} //查看命令協助
取字元值
注意:取值時,正數前面不需要加空格,負數前面需要加一個空格。
$alp 或${alp} 顯示字串內容
${#var} 顯示字串的長度
${var:offset:0} 顯示所有字串
${var:offset} 跳過前幾個字元,取後面的所有字元
${var:offset:length} 跳過前offset個字元,取其後面的length個字元
${var:offset:-length} 跳過前offset個字元和後length個字元,顯示中間的內容
${var: -length} 取字串的最右側幾個字元。注意:冒號後有一個空格,如${num: -3}
${var: -length: -offset} 取出字串的最右側幾個字元,然後在此基礎上,跳過後幾個字元,顯示剩餘字元。
${var: -length:length} 取出字串的最右側的幾個字元,然後在此基礎上,取出length個字元
alp=`echo {a..z}|tr -d " "` //顯示字串abcdefg..xyz
echo $alp //顯示字串
echo ${#alp} //查看字串的長度,即字元個數
echo ${alp:0} //顯示所有字串
echo ${alp:3} //跳過前3個字元,顯示後面所有字元
echo ${alp:3:5} //跳過前3個字元,取其後面的5個字元,顯示defgh
echo ${alp:3:-5} //跳過前3個字元和後5個字元,顯示中間的內容
echo ${alp: -3} //顯示最後3個字元,即xyz
echo ${alp: -3: -2} //先取出最右側的3個字元,然後再跳過後2個字元,即最後顯示字元x。
echo ${alp: -3:2} //先取出最右側的3個字元,然後取出前2個字元,即顯示為xy
刪除字元
${var#word} //刪除指定的前置詞字元
${var#*word} //從左往右,匹配刪除word本身及word之前的所有字元
${var##*word} //貪婪模式,匹配刪除最後的word本身及之前的所有字元
${var%word} //刪除指定的尾碼字元
${var%word*} //從右往左,匹配刪除word本身及word之後的所有字元。注意寫法*號在word右邊
${var%%word*} //貪婪模式,匹配刪除最後的word本身及之後的所有字元
url=http://www.baidu.com:80
echo ${url#http://}
echo ${url#*:}
echo ${url##*:} //取連接埠號碼
echo ${url%:80}
echo ${url%:*} //取網址
echo ${url%%:*} //取協議
取路徑和檔案名稱
file="/var/log/messages"
echo ${file#*/} //取相對路徑:var/log/messages
echo ${file##*/} //取檔案名稱:messages,相當於basename
echo ${file%/*} //取父目錄:/var/log,相當於dirname
尋找替換
${var/pattern/string} //尋找並替換第一次被匹配到的字元
${var//pattern/string} //尋找並替換所有被匹配到的字元
${var/#pattern/string} //尋找並替換行首匹配到的字元
${var/%pattern/string} //尋找並替換行尾匹配到的字元
a=abcabc
echo ${a/b/g} //匹配替換一次,顯示為agcabc
echo ${a//a/g} //匹配替換所有,顯示為gbcgbc
echo ${a/#a/g} //匹配替換行首,顯示為gbcabc
echo ${a/%c/g} //匹配替換行尾,顯示為abcabg
url=http://www.baidu.com:80
echo ${url/%80/8080} //替換連接埠為8080
尋找刪除
${var/pattern} //尋找並刪除第一次匹配到的字元
${var//pattern} //尋找並刪除所有匹配到的字元
${var/#pattern} //尋找並刪除行首匹配到的字元
${var/%pattern} //尋找並刪除行尾匹配到的字元
a=abcabc
echo ${a/b} //顯示為acabc
echo ${a//b} //acac
echo ${a/#a} //bcabc
echo ${a/%c} //abcab
轉換大小寫
${var^} //轉換首字母為大寫
${var^^} //把所有小寫字母轉換為大寫
${var,} //轉換首字母為小寫
${var,,} //把所有大寫字母轉換為小寫
a=abcabc
b=ABCABC
echo ${a^^} //小寫轉大寫
echo ${b,,} //大寫轉小寫
變數賦值檢測
${var:-word} 如果var值為空白或未設定,則返回word值,否則返回之前設定的var值
${var:+word} 如果var值為空白或未設定,則返回為空白,否則返回word值
${var:=word} 如果var值為空白或未設定,則設定var值為word值,即定義變數值,否則返回之前設定的var值
${var:?word} 如果var值為空白或未設定,則返回錯誤資訊word,否則返回之前設定的var值
a=abc
b=
echo ${a:-c} 顯示abc
echo ${b:-c} 顯示c
echo ${a:+c} 顯示c
echo ${b:+c} 顯示為空白
echo ${a:=c} 顯示為abc
echo ${b:=c} 顯示為c,並賦值給b
echo $b 顯示為c,即上述賦值生效
unset b
echo ${a:?c} 或 echo ${a:?} 顯示abc
#echo ${b:?} 未定義則預設顯示如下的錯誤資訊
-bash: b: parameter null or not set
#echo ${b:?this is error} 錯誤資訊顯示為自訂的語句或值
-bash: b: this is error
#echo ${b:?100}
-bash: b: 100
為所有指令碼使用一個獨立的變數檔案,統一所有變數,類似於獨立的函數檔案
echo "name=user1" > var //將所有的變數都放到檔案var中,以後的指令碼都調用此變數檔案即可
vi a.sh
#!/bin/bash
#a.sh
. var
echo your name is $name
執行./a.sh
eval 命令將會首先掃描命令列進行所有的置換,然後再執行該命令。該命令適用於那些一次掃描無法實現其功能的變數
cmd=whoami
# echo $cmd
whoami
# echo `$cmd`
# $cmd
# eval $cmd
echo `whoami`
eval whoami
echo `ll`
eval ll //保留源命令屬性,顯示的格式等
n=10
echo {1..$n} //無法正常顯示序列
eval echo {1..$n} //正常顯示數字序列1-10
間接變數引用
如果第一個變數的值是第二個變數的名字,從第一個變數引用第二個變數的值就稱為間接變數引用
兩種方式:eval var1=\$$var2 或 var1=${!var2}
a=b
b=c
eval echo \$$a //顯示為c
echo ${!a} //顯示為c
本文出自 “rackie” 部落格,請務必保留此出處http://rackie386.blog.51cto.com/11279229/1945757
shell編程進階之數組