在編寫shell scripts時,經常會用到括号,各種括号,各種用法。
一、小括号、圓括号:()
1、單小括号。
①指令組。括号中的指令将會新開一個子shell順序執行,是以括号中的變量不能夠被腳本餘下的部分使用。括号中多個指令之間用分号隔開,最後一個指令可以沒有分号,各指令和括号之間不必有空格。
②指令替換。等同于
cmd
,shell掃描一遍指令行,發現了 ( c m d ) 結 構 , 便 将 (cmd)結構,便将 (cmd)結構,便将(cmd)中的cmd執行一次,得到其标準輸出,再将此輸出放到原來指令。有些shell不支援,如tcsh。
a=$(ls) 等同于 a=`ls`
③用于初始化數組。如:array=(a b c d)
2、雙小括号。
①整數擴充。這種擴充計算是整數型的計算,不支援浮點型。((exp))結構擴充并計算一個算術表達式的值,如果表達式的結果為0,那麼傳回的退出狀态碼為0,或者 是"假",而一個非零值的表達式所傳回的退出狀态碼将為1,或者是"true"。若是邏輯判斷,表達式exp為真則為1,假則為0。
- 整數計算
-bash-4.1$ echo $((1+2))
3
- 條件為真傳回1,為假傳回0
-bash-4.1$ echo $((1<2))
1
-bash-4.1$ echo $((1>2))
0
- 條件判斷
if((1<2)); then
echo "1<2"
else
echo "1>2"
fi
輸出結果為:1<2
②隻要括号中的運算符、表達式符合C語言運算規則,都可用在$((exp))中,甚至是三目運算符。作不同進位(如二進制、八進制、十六進制)運算時,輸出結果全都自動轉化成了十進制。如:echo $((16#5f)) 結果為95 (16進位轉十進制)
③單純用 (( )) 也可重定義變量值,比如 a=5; ((a++)) 可将 $a 重定義為6
④雙括号中的變量可以不使用$符号字首。括号内支援多個表達式用逗号分開。
-bash-4.1$ a=1
-bash-4.1$ b=2
-bash-4.1$ ((a++,b++))
-bash-4.1$ echo $a, $b
2, 3
-bash-4.1$
二、中括号、方括号:[]
1、單中括号。
①bash 的内部指令,[和test是等同的。如果我們不用絕對路徑指明,通常我們用的都是bash自帶的指令。if/test結構中的左中括号是調用test的指令辨別,右中括号是關閉條件判斷的。這個指令把它的參數作為比較表達式或者作為檔案測試,并且根據比較的結果來傳回一個退出狀态碼。if/test結構中并不是必須右中括号,但是新版的Bash中要求必須這樣。
②Test和[]中可用的比較運算符隻有==和!=,兩者都是用于字元串比較的,不可用于整數比較,整數比較隻能使用-eq,-gt這種形式。無論是字元串比較還是整數比較都不支援大于号小于号。如果實在想用,對于字元串比較可以使用轉義形式,如果比較"ab"和"bc":[ ab < bc ],結果為真,也就是傳回狀态為0。[ ]中的邏輯與和邏輯或使用-a 和-o 表示。
if [ 'a' == 'b' ]; then
echo "a=b"
else
echo "a!=b"
fi
if [ 1 -lt 2 ]; then
echo '1<2'
else
echo '1>2'
fi
if [ 1 \< 2 ]; then
echo '1<2'
else
echo '1>2'
fi
輸出結果:
a!=b
1<2
1<2
③字元範圍。用作正規表達式的一部分,描述一個比對的字元範圍。作為test用途的中括号内不能使用正則。
④在一個array 結構的上下文中,中括号用來引用數組中每個元素的編号。
⑤表達式計算
-bash-4.1$ count=1
-bash-4.1$ echo $[${count} + 1]
2
2、雙中括号。
①[[是 bash 程式語言的關鍵字。并不是一個指令,[[ ]] 結構比[ ]結構更加通用。在[[和]]之間所有的字元都不會發生檔案名擴充或者單詞分割,但是會發生參數擴充和指令替換。
②支援字元串的模式比對,使用=~操作符時甚至支援shell的正規表達式。字元串比較時可以把右邊的作為一個模式,而不僅僅是一個字元串,比如[[ hello == hell? ]],結果為真。[[ ]] 中比對字元串或通配符,不需要引号。
if [[ abcdefg =~ ^[a-z0-9]+$ ]]; then
echo "match"
else
echo "no match"
fi
if [[ "012345abc" =~ ^[0-9]+$ ]]; then
echo "match"
else
echo "no match"
fi
輸出結果:
match
no match
③使用[[ … ]]條件判斷結構,而不是[ … ],能夠防止腳本中的許多邏輯錯誤。比如,&&、||、<和> 操作符能夠正常存在于[[ ]]條件判斷結構中,但是如果出現在[ ]結構中的話,會報錯。
if [[ 1 < 2 ]]; then
echo '1<2'
else
echo '1>2'
fi
輸出結果:1<2
④bash把雙中括号中的表達式看作一個單獨的元素,并傳回一個退出狀态碼。
三、大括号、花括号:{}
1、正常用法。
①大括号拓展。(通配(globbing))将對大括号中的檔案名做擴充。在大括号中,不允許有空白,除非這個空白被引用或轉義。第一種:對大括号中的以逗号分割的檔案清單進行拓展。如 touch {a,b}.txt 結果為a.txt b.txt。第二種:對大括号中以點點{…}分割的順序檔案清單起拓展作用,如:touch {a…d}.txt 結果為a.txt b.txt c.txt d.txt
②代碼塊,又被稱為内部組,這個結構事實上建立了一個匿名函數 。與小括号中的指令不同,大括号内的指令不會新開一個子shell運作,即腳本餘下部分仍可使用括号内變量。括号内的指令間用分号隔開,最後一個也必須有分号。{}的第一個指令和左括号之間必須要有一個空格。
③擷取變量
-bash-4.1$ a='123'
-bash-4.1$ echo ${a}
123
-bash-4.1$
注:擷取變量也可以通過$a,但是${a}比較标準,推薦通過這種方式獲
2、特殊用法。
例如: v a r : − s t r i n g 、 {var:-string}、 var:−string、{var#*/}、KaTeX parse error: Expected '}', got 'EOF' at end of input: {var%%.*}、{var:5:5}等單獨作為一篇記錄。
(詳細特殊用法參考http://m.blog.chinaunix.net/uid-22606185-id-4023973.html)
-bash-4.1$ a='12345'
-bash-4.1$ echo ${a:1:2}
23
四)例子:
if ($i<5)
if [ $i -lt 5 ]
if [ $a -ne 1 -a $a != 2 ]
if [ $a -ne 1] && [ $a != 2 ]
if [[ $a != 1 && $a != 2 ]]
for i in $(seq 0 4);do echo $i;done
for i in `seq 0 4`;do echo $i;done
for ((i=0;i<5;i++));do echo $i;done
for i in {0..4};do echo $i;done
看到上面的例子就知道了,各種括号,各種用法,一個問題可以用幾種不同的方法解決,但是在節約代碼的同時,也要照顧到腳本的可讀性,可移植性,盡量使用風險小的,可移植性好的,不要隻圖省事,養成一個良好的代碼風格。
五)expr用法
①運算表達式用法
-bash-4.1$ count=1
-bash-4.1$ num=2
-bash-4.1$ echo `expr $count + $num`
-bash-4.1$ echo $[${count} + ${num}]
-bash-4.1$ echo $((${count} + ${num}))
-bash-4.1$ echo $[${count} + 1]
補充:變量名外面的花括号是可選的,加不加都行,加花括号是為了幫助解釋器識别變量的邊界,例如echo "I am good at s k i l l S c r i p t " , 如 果 不 加 花 括 号 解 釋 器 就 會 把 {skill}Script",如果不加花括号解釋器就會把 skillScript",如果不加花括号解釋器就會把skillScript當成一個變量
②運算
-bash-4.1$ expr 2 + 2
-bash-4.1$ expr 3 - 2
-bash-4.1$ expr 1 \* 2
-bash-4.1$ expr 3 / 2
-bash-4.1$ expr 3 % 2
注:進行乘法運算時需要轉義*
③正則比對,傳回分組結果,每次隻能設定一個分組
dir=`expr "a/b/c/1.log" : '.*/\(.*\)/[0-9]\+.log$'`
name=`expr "a/b/c/1.log" : '.*/\([0-9]\+\).log$'`
輸出結果:
c
1
④match用法
-bash-4.1$ expr match "abcde" "a"
-bash-4.1$ expr match "abcde" "b"
-bash-4.1$ expr match "abcde" ".*b"
-bash-4.1$ expr match "abcde" ".*c"
-bash-4.1$ expr match "abcde" ".*cd"
-bash-4.1$ expr match "abcde" ".*ed"
-bash-4.1$ expr match "abcde" ".*cde"
比對時傳回字元所在下标,下标從1開始,字元串時,傳回最後一個字元所在下标
⑤字元串操作
-bash-4.1$ expr substr "abcdefg" 1 3
abc
-bash-4.1$ expr index "abc" a
-bash-4.1$ expr length "abcde"
注:
-bash-4.1$ a='12345'
-bash-4.1$ echo ${a:1:2}
字元串截取
-bash-4.1$ expr substr "abcdefg" 1 3
abc
-bash-4.1$ echo $v1
abc1234zip1234abc
-bash-4.1$ echo ${v1:(-2)}
bc
index 傳回字元下标
字元串長度
${#string}
expr length $string
expr "$string" : '.*'
expr相關用法:
STRING : REGEXP anchored pattern match of REGEXP in STRING
match STRING REGEXP same as STRING : REGEXP
substr STRING POS LENGTH substring of STRING, POS counted from 1
index STRING CHARS index in STRING where any CHARS is found, or 0
length STRING length of STRING
資料分享
java學習筆記、10T資料、100多個java項目分享
歡迎關注個人公衆号【菜鳥名企夢】,公衆号專注:網際網路求職面經、java、python、爬蟲、大資料等技術分享**:
公衆号**
菜鳥名企夢
背景發送“csdn”即可免費領取【csdn】和【百度文庫】下載下傳服務;
公衆号
菜鳥名企夢
背景發送“資料”:即可領取5T精品學習資料**、java面試考點和java面經總結,以及幾十個java、大資料項目,資料很全,你想找的幾乎都有