模式匹配在Shell腳本中的運用很廣泛妓湘。
舉幾個栗子:
"三元運算符"
#!/usr/bin/env bash
x=${1:-"hello"}
echo $x
# 打印第一個參數(shù)(默認hello)
在上述例子中雄嚣,x=${1:-"hello"}
中的 1:-
可以理解為三元運算符的匹配條件,表達的含義是,如果參數(shù)列表中 $1
的值不為空鸣个,則 x
值為 $1
辑畦,否則值為"hello"吗蚌。表達式中的 -
則可以理解為是該表達式的匹配模式,另外還有 +
=
?
三種模式:
${var:-string}和${var:=string}:若變量var為空纯出,則用在命令行中用string來替換${var:-string}蚯妇,否則變量var不為空時敷燎,則用變量var的值來替換${var:-string};對于${var:=string}的替換規(guī)則和${var:-string}是一樣的箩言,所不同之處是${var:=string}若var為空時硬贯,用string替換${var:=string}的同時,把string賦給變量var: ${var:=string}很常用的一種用法是陨收,判斷某個變量是否賦值饭豹,沒有的話則給它賦上一個默認值。
${var:+string}的替換規(guī)則和上面的相反务漩,即只有當var不是空的時候才替換成string拄衰,若var為空時則不替換或者說是替換成變量 var的值,即空值饵骨。(因為變量var此時為空肾砂,所以這兩種說法是等價的)
${var:?string}替換規(guī)則為:若變量var不為空,則用變量var的值來替換${var:?string}宏悦;若變量var為空镐确,則把string輸出到標準錯誤中,并從腳本中退出饼煞。我們可利用此特性來檢查是否設(shè)置了變量的值源葫。
補充擴展:在上面這五種替換結(jié)構(gòu)中string不一定是常值的,可用另外一個變量的值或是一種命令的輸出砖瞧。
模式匹配記憶方法:
# 是去掉左邊(在鍵盤上#在$之左邊)
% 是去掉右邊(在鍵盤上%在$之右邊)
# 和 % 中的單一符號是最小匹配息堂,兩個相同符號是最大匹配。
${var%pattern}, ${var%%pattern}, ${var#pattern}, ${var##pattern}
- 第一種模式:${variable%pattern}块促,這種模式時荣堰,shell 在 variable 中查找,看它是否一給的模式 pattern 結(jié)尾竭翠,如果是振坚,就從命令行把 variable 中的內(nèi)容去掉右邊最短的匹配模式;
- 第二種模式: ${variable%%pattern}斋扰,這種模式時渡八,shell 在 variable 中查找,看它是否一給的模式 pattern 結(jié)尾传货,如果是屎鳍,就從命令行把 variable 中的內(nèi)容去掉右邊最長的匹配模式;
- 第三種模式:${variable#pattern} 這種模式時问裕,shell 在 variable 中查找逮壁,看它是否一給的模式 pattern 開始,如果是粮宛,就從命令行把 variable 中的內(nèi)容去掉左邊最短的匹配模式窥淆;
- 第四種模式: ${variable##pattern} 這種模式時十饥,shell 在 variable 中查找,看它是否一給的模式 pattern 結(jié)尾祖乳,如果是,就從命令行把 variable 中的內(nèi)容去掉右邊最長的匹配模式秉氧;
- 這四種模式中都不會改變 variable 的值眷昆,其中,只有在 pattern 中使用了 * 匹配符號時汁咏,% 和 %%亚斋,# 和 ## 才有區(qū)別。結(jié)構(gòu)中的 pattern 支持通配符攘滩,* 表示零個或多個任意字符帅刊,? 表示僅與一個任意字符匹配,[...] 表示匹配中括號里面的字符漂问,[!...] 表示不匹配中括號里面的字符赖瞒。
# var=testcase
# echo $var
testcase
# echo ${var%s*e}
testca
# echo $var
testcase
# echo ${var%%s*e}
te
# echo ${var#?e}
stcase
# echo ${var##?e}
stcase
# echo ${var##*e}
# echo ${var##*s}
e
# echo ${var##test}
case
字符串提取和替換
${var:num},${var:num1:num2},${var/pattern/pattern},${var//pattern/pattern}
- 第一種模式:${var:num},這種模式時蚤假,shell在var中提取第num個字符到末尾的所有字符栏饮。若num為正數(shù),從左邊0處開始磷仰;若num為負數(shù)袍嬉,從右邊開始提取字串,但必須使用在冒號后面加空格或一個數(shù)字或整個num加上括號灶平,如${var: -2}伺通、${var:1-3}或${var:(-2)}。
- 第二種模式:${var:num1:num2}逢享,num1是位置罐监,num2是長度。表示從$var字符串的第$num1個位置開始提取長度為$num2的子串瞒爬。不能為負數(shù)笑诅。
- 第三種模式:${var/pattern/pattern}表示將var字符串的第一個匹配的pattern替換為另一個pattern。
- 第四種模式:${var//pattern/pattern}表示將var字符串中的所有能匹配的pattern替換為另一個pattern。
var=/home/centos
# echo $var
/home/centos
# echo ${var:5}
/centos
# echo ${var: -6}
centos
# echo ${var:(-6)}
centos
# echo ${var:1:4}
home
# echo ${var/o/h}
/hhme/centos
# echo ${var//o/h}
/hhme/cenths
end.