標籤:不同 英文單詞 hle blank 技術 shel (()) 字元截取 img
本文主要講bash指令碼中容易出錯和很少用但是用起來有意想不到效果的部分。
迴圈:
正常的for迴圈:
for i in a b c 1 2 3; do echo "$i"done
數字序列迴圈:
for i in `seq 100`; do echo "$i"done
其中的 `seq 100` 也可以換成 {1..100}
{開始..結尾}的這種形式可以表示連續的數列,可以從小到大也可以從大到小,但是可惜不像python的range()那樣可以指定間隔量
C語言風格的for迴圈:
for (( i=1; i<100; i++ )); do echo "$i"done
數學計算
雙括弧“(())”還可以用於數學計算:
(( a=123+456 ))echo $a# 579
在雙括弧中,變數並不需要用$符號來引用,英文單詞天然是變數。
變數:間接引用:
a=bb=100echo ${!a}# 100
效果等同於 eval echo \$$a
字串操作
變數值的字元長度:
a="abcdefg"echo ${#a}# 7
變數值字元截取:
a="abcdefg"echo ${a:2}# cdefgecho ${a:2:3}# cde
變數值字元刪除:(#為從頭部開始匹配,%為從尾部匹配,支援萬用字元“?*”)
a="abdcdefgh"echo ${a#*d} # 刪除字串頭部匹配“*d”的部分,萬用字元*代表匹配任意多個字元,一個#號代表萬用字元“*”保守匹配# cdefghecho ${a##*d} # 兩個#號表示貪婪匹配# efghecho ${a%d*} # 同上,兩個%時代表貪婪匹配# abdc
a=bb="abcdefg"echo "${!a#abc}"# defg
可以同時支援間接引用和字元刪除
變數賦值安全
用於賦值前檢查是否已經定義或賦值。
unset aunset bb="" # a沒有定義,b定義了但是空值echo ${a-789} # 如果沒定義,則運算式採用預設值789# 789echo ${a:-789} # 如果沒定義或是空值,則運算式採用預設值789# 789echo ${b-789} # 如果沒定義,則運算式採用預設值789,b定義了# echo ${b:-789} # 如果沒定義或是空值,則運算式採用預設值789# 789echo $a # 原變數並沒有被賦值#echo $b # 原變數並沒有被賦值#b=123echo ${b-789} # 如果變數已經被賦值,則不改變原有值# 123
unset aecho ${a=789} # 如果a沒定義,則運算式採用預設值,並給a賦值# 789echo $a# 789 # a已經被賦值了a=""echo ${a=789}#echo ${a:=789} # 加冒號:的作用和之前一樣# 789echo $a# 789
前面講了用“-”和“=”的,還有一種用“+”的,用於當變數已經被賦值的情況下採用預設值,舉一反三,不贅述了。
位置變數
$0是檔案名稱,$#代表參數個數,$1,$2等等表示執行該指令碼或函數後面跟的位置參數,$1代表第一個參數,依次類推,需要注意的是,第9個以後的參數應該這麼表示:
${10}
這表示第10個參數,必須用花括弧括起來,否則就變成第1個變數後面加個字元“0”了。因為這個有的人以為第9個以後的位置變數就不可用了,是錯的。
[email protected]和$*都表示所有的變數,但是區別是前者將每個作為一個字串,是多個字串的結合,而後者將所有變數組合成一個字串,用空格分隔。
這樣不同會在for迴圈裡面造成使用的區別,在for迴圈裡面,如果加上引號 for i in "[email protected]" 和 for i in "$*" 是不同的,前者還是會依次把參數代入迴圈,而後者會吧所有參數作為字串一次性代入:
echo ‘for i in "[email protected]"; do echo "$i"donefor i in "$*"; do echo "$i"done‘ > myscript.shchmod 755 myscript.sh./myscript.sh abc 123 def
結果是:
abc123defabc 123 def
那麼[email protected]加引號和不加引號有區別嗎?
大部分情況下結果看起來是一樣的,但會在某些情況下造成麻煩,因為for迴圈會用分行符號“\n”和空格來拆分變數,所以如果呼叫指令碼所帶的參數中帶有空格或者分行符號,不加引號的時候會把這個參數拆開了依次代入,而加了引號就可以避免這種情況。
echo ‘for i in "[email protected]"; do echo "$i"donefor i in [email protected] ; do echo "$i"done‘ > myscript.shchmod 755 myscript.sh./myscript.sh abc "123 def"
結果是:
abc123 defabc123def
for迴圈使用數組
將數組的值依次代入迴圈,可以用${arr[@}和${arr[*]}這兩種方法,區別和加引號的區別同上面位置參數的使用相同。
字串匹配
shell的字串匹配通常是這樣的:
[ "abc" = "abc" ]echo $?# 0
若字串相同則返回0,否則返回1。除了全匹配外,通過雙方括弧“[[]]”還可以用Regex匹配
[[ "abc234def" =~ ^abc[0-9]{3}[a-z]+$ ]]echo $?# 0
注意這裡Regex不能用引號括起來,而且只支援基本的正則,不支援如“\b \S”之類的擴充。
原文地址:http://www.cnblogs.com/foxgab/p/6901782.html
如果覺得本文對您有協助,請掃描後面的二維碼給予捐贈,您的支援是作者繼續寫出更好文章的動力!
linux shell編程-bash的奇技淫巧