參考:http://www.zsythink.net/archives/2276
在shell中,當我們已經獲取到某個變量的變量值的時候,可能還需要對變量值進行一定的處理,才能到我們最終想要的結果,今天我們就來聊聊shell中常見的變量處理方法,我們通常會對變量進行如下處理。
一、獲取變量的長度(字符串長度)。
二、對變量值進行截取(截取字符串)。
三、替換變量值中的某段字符。
四、刪除變量值中的某段字符。
五、對變量值進行大小寫轉換。
六、當變量值為空時,對變量進行一些操作。
上述處理都是一些常見的操作,我們一個一個慢慢聊,這篇文章中,我們只對前兩種操作進行總結,即怎樣獲取變量長度,以及怎樣對變量值進行截取。
一、獲取變量長度
通常,我們有可能需要獲取變量值的長度,比如,變量中存放了一個字符串,我們需要獲取字符串的長度,則可以使用如下方法。
[root@node1 ~]# website="www.baidu.com" [root@node1 ~]# echo $website www.baidu.com [root@node1 ~]# echo ${#website} 13 [root@node1 ~]#
如上圖所示,website變量的值為"www.baidu.com","www.baidu.com"字符串一共由16個字符組成,當輸出${#website}時,即可輸出變量website的長度,很簡單吧。
二、截取變量
有時候,我們只是需要變量值中的某一段,所以,我們需要截取這段內容為我們所用。而截取變量的方法又有不少,我們一一道來。
從指定位置開始截取字符串
通常,我們需要從指定的位置開始截取字符串,截取到字符串的末尾,示例如下。
[root@node1 ~]# website="www.zsythink.net" [root@node1 ~]# echo ${website:4} zsythink.net [root@node1 ~]#
上例中的":4"表示從website變量值的第4個字符開始,截取到變量值的末尾。
上例中的":0-4"表示從website變量值的倒數第4個字符開始,截取到變量值的末尾。
從上例可以看出,":0-4"中的"0"可以使用"空格"代替,效果是相同的,但是,從上例中可以看出,"冒號"與"負號"之間如果不存在任何字符,則無法起到截取字符的效果,所以,上圖中第三種寫法是錯誤的。
從指定位置開始截取字符串,並且指定截取字符的長度
除了能夠指定截取操作的開始位置,我們還能夠指定截取的長度,比如,從變量的第4個字符開始截取,截取8個字符的長度,示例如下。
[root@node1 ~]# echo ${website:4:8} zsythink [root@node1 ~]#
聰明如你一定想到了,我們能不能從倒數的位置開始,截取指定長度的字符呢?必須能的,示例如下。
如上圖所示,":0-12:9"表示從倒數第12個字符開始,向后截取9個字符,與之前的示例同理,"冒號"與"負號"之間如果不存在任何字符,則無法起到截取字符的效果,所以,上圖中第三種寫法是錯誤的。
在上述示例中,我們指定了截取字符的長度,比如上例中的":0-12:9",表示截取9個字符的長度,其實,在centos7中,我們可以將截取字符的長度指定為"負數",但是注意,centos6中截取字符串的長度不能為"負數",否則會報錯,我們來看看在centos7中,將截取長度指定為"負數"后的效果。示例如下
[root@node1 ~]# cat /etc/redhat-release CentOS Linux release 7.8.2003 (Core) [root@node1 ~]# website="www.zsythink.net" [root@node1 ~]# echo ${website:0-12} zsythink.net [root@node1 ~]# echo ${website:0-12:-4} zsythink
如上圖所示,在centos7中,":0-12"表示從倒數第12個字符開始,向后截取所有字符,當同時指定截取長度為":-4"時,表示從倒數第12個字符向后截取所有字符以后,刪除截取以后的字符的最后4個字符,換句話說,也可以理解成截取最后12個字符的前8個字符。
但是,使用上述方法是需要注意一點,刪除截取以后的字符數量不能大於現有字符的數量,示例如下。
[root@node1 ~]# echo ${website:0-12:-4} zsythink [root@node1 ~]# echo ${website:0-12:-11} z [root@node1 ~]# echo ${website:0-12:-12} [root@node1 ~]# echo ${website:0-12:-13} -bash: -13: 子串表達式 < 0 [root@node1 ~]#
如上圖所示,我們一共就截取了12個字符,如果將截取長度指定為"-13",則會報上述錯誤:-bash: XX : substring expression < 0
注意:在centos7中,使用這種寫法的時候要計算好截取的范圍,否則會報錯
掐頭去尾截取之掐頭截取
所謂的"掐頭去尾",其實就是刪除某個字符左側的所有字符(掐頭),或者刪除某個字符右側的所有字符(去尾),這樣說可能不容易理解,我們來看一些小例子,就能明白了。
先從所謂的"掐頭"聊起,示例如下。
[root@node1 ~]# website="www.zsythink.net" [root@node1 ~]# echo ${website} www.zsythink.net [root@node1 ~]# echo ${website#*.} zsythink.net [root@node1 ~]#
如上例所示,我們使用"#*."即可刪除字符串中從左向右數第一個 "." 以及其左側的全部字符,這就是所謂"掐頭去尾"中的掐頭,准確的說,應該是掐去頭部,截取尾部。
聰明如你一定已經會舉一反三了,我們可以把上例中的 "." 替換成其他字符,也是同樣適用的,示例如下。
[root@node1 ~]# teststr=bbAccAddAeeA [root@node1 ~]# echo ${teststr#*A} ccAddAeeA [root@node1 ~]#
如上圖所示,"#*A"表示刪除字符串中從左向右第一個遇到的A,以及其左側的字符。
換句話說,從左向右第一個遇到的A以及其左側的字符都被當做"頭部"掐去了。
其實,除了能夠使用"#*字符"的語法進行"掐頭",其實還有另一種方法,也能實現"掐頭"的操作,只不過它們略有些不同,示例如下。
[root@node1 ~]# website="www.zsythink.net" [root@node1 ~]# echo ${website} www.zsythink.net [root@node1 ~]# echo ${website#*.} zsythink.net [root@node1 ~]# echo ${website##*.} net [root@node1 ~]#
如上例所示,"##*."表示刪除字符串中從左向右最后一個遇到的 "." ,以及其左側的字符。
換句話說,從左向右最后一個遇到的 "." 以及其左側的字符都被當做"頭部"掐去了。
沒錯,通過上例即可對比出兩種寫法的不同。
"#*."表示刪除字符串中從左向右第一個遇到的 "." ,以及其左側的字符。
"##*."表示刪除字符串中從左向右最后一個遇到的 "." ,以及其左側的字符。
當然,上例中的"."也是可以根據實際情況替換成其他字符的,示例如下。
[root@node1 ~]# testpath="/usr/local/nginx/conf.d" [root@node1 ~]# echo ${testpath} /usr/local/nginx/conf.d [root@node1 ~]# echo ${testpath##*/} conf.d [root@node1 ~]#
掐頭去尾截取之去尾截取
與之前描述的"掐頭截取"相似,只要理解了之前的示例,再來理解"去尾截取",簡直不要太簡單。
我們先來看一個小示例。
[root@node1 ~]# testpath="/usr/local/nginx/conf.d" [root@node1 ~]# echo ${testpath%/*} /usr/local/nginx [root@node1 ~]#
如上圖所示,"%/*"表示刪除字符串中從右向左第一個遇到的 "/" ,以及其右側的字符。
換句話說,從右向左第一個遇到的 "/" 以及其右側的字符都被當做"尾部"去掉了。
舉一反三,我們可以根據實際情況,將上例中的"/"替換成別的字符,示例如下。
[root@node1 ~]# echo ${website} www.zsythink.net [root@node1 ~]# echo ${website%.*} www.zsythink [root@node1 ~]#
聰明如你,一定想到了,"去尾"截取法不止有上述一種方法,還有另一種"去尾"截取法,它們之間也略有不同,示例如下
[root@node1 ~]# website="https://www.zsythink/index.html" [root@node1 ~]# echo ${website} https://www.zsythink/index.html [root@node1 ~]# echo ${website%/*} https://www.zsythink [root@node1 ~]# echo ${website%%/*} https: [root@node1 ~]#
上例中,"%%/*"表示刪除字符串中從右向左最后一個遇到的 "/" ,以及其右側的字符。
換句話說,從右向左最后一個遇到的 "/" 以及其右側的字符都被當做"尾部"去掉了。