天天看點

bash shell中的括号及expr用法

在編寫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 &quot; , 如 果 不 加 花 括 号 解 釋 器 就 會 把 {skill}Script&quot;,如果不加花括号解釋器就會把 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、大資料項目,資料很全,你想找的幾乎都有

bash shell中的括号及expr用法

繼續閱讀