Shell字符串截取操作

Shell 截取字符串通常有兩種方式:從指定位置開始截取和從指定字符(子字符串)開始截取。
從指定位置開始截取
這種方式需要兩個參數:除了指定起始位置,還需要截取長度,才能最終確定要截取的字符串。

既然需要指定起始位置,那麼就涉及到計數方向的問題,到底是從字符串左邊開始計數,還是從字符串右邊開始計數。答案是 Shell 同時支持兩種計數方式。

  1. 從字符串左邊開始計數
    如果想從字符串的左邊開始計數,那麼截取字符串的具體格式如下:
${string: start :length}

其中,string 是要截取的字符串,start 是起始位置(從左邊開始,從 0 開始計數),length 是要截取的長度(省略的話表示直到字符串的末尾)。

例如:

[dwzq@localhost ft_cli]$ time=`date +%Y%m%d%H%M%S`
[dwzq@localhost ft_cli]$ format_time=${time: 0: 4}"-"${time: 4: 2}"-"${time: 6: 2}" "${time: 8: 2}":"${time: 10: 2}":"${time: 12: 2}
[dwzq@localhost ft_cli]$ echo $format_time
2020-04-07 10:12:50

再如:
url="c.biancheng.net"
echo ${url: 2}  #省略 length,截取到字符串末尾
結果爲biancheng.net。
2) 從右邊開始計數
如果想從字符串的右邊開始計數,那麼截取字符串的具體格式如下:
${string: 0-start :length}

同第 1) 種格式相比,第 2) 種格式僅僅多了0-,這是固定的寫法,專門用來表示從字符串右邊開始計數。

這裏需要強調兩點:
從左邊開始計數時,起始數字是 0(這符合程序員思維);從右邊開始計數時,起始數字是 1(這符合常人思維)。計數方向不同,起始數字也不同。
不管從哪邊開始計數,截取方向都是從左到右。

例如:
url="c.biancheng.net"
echo ${url: 0-13: 9}
結果爲biancheng。從右邊數,b是第 13 個字符。

再如:
url="c.biancheng.net"
echo ${url: 0-13}  #省略 length,直接截取到字符串末尾
結果爲biancheng.net。
從指定字符(子字符串)開始截取
這種截取方式無法指定字符串長度,只能從指定字符(子字符串)截取到字符串末尾。Shell 可以截取指定字符(子字符串)右邊的所有字符,也可以截取左邊的所有字符。
1) 使用 # 號截取右邊字符
使用#號可以截取指定字符(或者子字符串)右邊的所有字符,具體格式如下:
${string#*chars}

其中,string 表示要截取的字符,chars 是指定的字符(或者子字符串),*是通配符的一種,表示任意長度的字符串。*chars連起來使用的意思是:忽略左邊的所有字符,直到遇見 chars(chars 不會被截取)。

請看下面的例子:
url="http://c.biancheng.net/index.html"
echo ${url#*:}
結果爲//c.biancheng.net/index.html。

以下寫法也可以得到同樣的結果:
echo ${url#*p:}
echo ${url#*ttp:}

如果不需要忽略 chars 左邊的字符,那麼也可以不寫*,例如:
url="http://c.biancheng.net/index.html"
echo ${url#http://}
結果爲c.biancheng.net/index.html。

注意,以上寫法遇到第一個匹配的字符(子字符串)就結束了。例如:

url="http://c.biancheng.net/index.html"
echo ${url#*/}
結果爲/c.biancheng.net

/index.html。url 字符串中有三個/,輸出結果表明,Shell 遇到第一個/就匹配結束了。

如果希望直到最後一個指定字符(子字符串)再匹配結束,那麼可以使用##,具體格式爲:

${string##*chars}

請看下面的例子:

#!/bin/bash
url="http://c.biancheng.net/index.html"
echo ${url#*/}    #結果爲 /c.biancheng.net/index.html
echo ${url##*/}   #結果爲 index.html
str="---aa+++aa@@@"
echo ${str#*aa}   #結果爲 +++aa@@@
echo ${str##*aa}  #結果爲 @@@
  1. 使用 % 截取左邊字符
    使用%號可以截取指定字符(或者子字符串)左邊的所有字符,具體格式如下:
    ${string%chars*}

請注意的位置,因爲要截取 chars 左邊的字符,而忽略 chars 右邊的字符,所以應該位於 chars 的右側。其他方面%和#的用法相同,這裏不再贅述,僅舉例說明:

#!/bin/bash
url="http://c.biancheng.net/index.html"
echo ${url%/*}  #結果爲 http://c.biancheng.net
echo ${url%%/*}  #結果爲 http:
str="---aa+++aa@@@"
echo ${str%aa*}  #結果爲 ---aa+++
echo ${str%%aa*}  #結果爲 ---

彙總

最後,我們對以上 8 種格式做一個彙總,請看下錶:

格式 說明
${string: start :length} 從 string 字符串的左邊第 start 個字符開始,向右截取 length 個字符。
${string: start} 從 string 字符串的左邊第 start 個字符開始截取,直到最後。
${string: 0-start :length} 從 string 字符串的右邊第 start 個字符開始,向右截取 length 個字符。
${string: 0-start} 從 string 字符串的右邊第 start 個字符開始截取,直到最後。
${string#*chars} 從 string 字符串第一次出現 *chars 的位置開始,截取 *chars 右邊的所有字符。
${string##*chars} 從 string 字符串最後一次出現 *chars 的位置開始,截取 *chars 右邊的所有字符。
${string%*chars} 從 string 字符串第一次出現 *chars 的位置開始,截取 *chars 左邊的所有字符。
${string%%*chars} 從 string 字符串最後一次出現 *chars 的位置開始,截取 *chars 左邊的所有字符。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章