天天看點

【shell】Shell中字元串截取詳解從指定位置開始截取彙總

文章目錄

  • 從指定位置開始截取
    • 從字元串左邊開始計數
    • 從右邊開始計數
    • 從指定字元(子字元串)開始截取
      • 使用 # 号截取右邊字元
      • 使用 % 截取左邊字元
  • 彙總

Shell 截取字元串通常有兩種方式:從指定位置開始截取和從指定字元(子字元串)開始截取。

從指定位置開始截取

這種方式需要兩個參數:除了指定起始位置,還需要截取長度,才能最終确定要截取的字元串。

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

從字元串左邊開始計數

如果想從字元串的左邊開始計數,那麼截取字元串的具體格式如:

${string: start: length}

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

例如:

url="https://blog.csdn.net/lz6363/"
echo ${url: 8: 4}

結果為blog
           

再如:

url="https://blog.csdn.net/lz6363/"
echo ${url: 8}  #省略 length,截取到字元串末尾

結果為blog.csdn.net/lz6363/
           

從右邊開始計數

如果想從字元串的右邊開始計數,那麼截取字元串的具體格式如:

${string: 0-start: length}

同從做到右格式相比,此種格式僅僅多了0-,這是固定的寫法,專門用來表示從字元串右邊開始計數。

這裡需要強調兩點:

從左邊開始計數時,起始數字是 0(這符合程式員思維);從右邊開始計數時,起始數字是 1(這符合常人思維)。計數方向不同,起始數字也不同。

不管從哪邊開始計數,截取方向都是從左到右。

例如:

url="https://blog.csdn.net/lz6363/"
echo ${url: 0-21: 4} #從右邊數,b是第21個字元

結果為blog
           

再如:

url="https://blog.csdn.net/lz6363/"
echo ${url: 0-21}  #省略 length,直接截取到字元串末尾

結果為blog.csdn.net/lz6363/
           

從指定字元(子字元串)開始截取

這種截取方式無法指定字元串長度,隻能從指定字元(子字元串)截取到字元串末尾。Shell 可以截取指定字元(子字元串)右邊的所有字元,也可以截取左邊的所有字元。

使用 # 号截取右邊字元

使用#号可以截取指定字元(或者子字元串)右邊的所有字元,具體格式如:

${string#*chars}

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

請看下面的例子:

url="https://blog.csdn.net/lz6363/"
echo ${url#*://}

結果為blog.csdn.net/lz6363/
           

以下寫法也可以得到同樣的結果:

echo ${url#*s://}
echo ${url#*//}
           

如果不需要忽略 chars 左邊的字元,那麼也可以不寫*,例如:

url="https://blog.csdn.net/lz6363/"
echo ${url#https://}

結果為blog.csdn.net/lz6363/
           

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

url="https://blog.csdn.net/lz6363/"
echo ${url#*/} # url 字元串中有四個/,輸出結果表明,Shell 遇到第一個/就比對結束了。

結果為/blog.csdn.net/lz6363/
           

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

${string##*chars}

請看下面的例子:

#!/bin/bash
url="https://blog.csdn.net/lz6363"
echo ${url#*/}    #結果為 /blog.csdn.net/lz6363
echo ${url##*/}   #結果為 lz6363
str="[email protected]@@"
echo ${str#*aa}   #結果為 [email protected]@@
echo ${str##*aa}  #結果為 @@@
           

使用 % 截取左邊字元

使用%号可以截取指定字元(或者子字元串)左邊的所有字元,具體格式如:

${string%chars*}

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

#!/bin/bash
url="https://blog.csdn.net/lz6363"
echo ${url%/*}  #結果為 https://blog.csdn.net
echo ${url%%/*}  #結果為 https:
str="[email protected]@@"
echo ${str%aa*}  #結果為 ---aa+++
echo ${str%%aa*}  #結果為 ---
           

彙總

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

格式 說明
${string: start: length} 從 string 字元串的左邊第 start 個字元開始(起始位置為0),向右截取 length 個字元。
${string: start} 從 string 字元串的左邊第 start 個字元開始截取,直到最後。
${string: 0-start: length} 從 string 字元串的右邊第 start 個字元開始(起始位置為1),向右截取 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 左邊的所有字元。

繼續閱讀