??Bash shell 學習筆記(1)——字串操作
??1.字串的長度
??獲取字串長度的語法如下,
${#varname}
??下面是一個例子,
$ myPath=/home/cam/book/long.file.name
$ echo ${#myPath}
29
??大括號{}是必需的,否則 Bash 會將$#理解成腳本的引數個數,將變數名理解成文本,
$ echo $#myvar
0myvar
??上面例子中,Bash 將$#和myvar分開解釋了,
??2.子字串
??字串提取子串的語法如下,
${varname:offset:length}
  上面語法的含義是回傳變數$varname的子字串,從位置offset開始(從0開始計算),長度為length,
$ count=frogfootman
$ echo ${count:4:4}
foot
??上面例子回傳字串frogfootman從4號位置開始的長度為4的子字串foot,
??這種語法不能直接操作字串,只能通過變數來讀取字串,并且不會改變原始字串,變數前面的美元符號可以省略,
# 報錯
$ echo ${"hello":2:3}
??上面例子中,"hello"不是變數名,導致 Bash 報錯,
??如果省略length,則從位置offset開始,一直回傳到字串的結尾,
$ count=frogfootman
$ echo ${count:4}
footman
??上面例子是回傳變數count從4號位置一直到結尾的子字串,
??如果offset為負值,表示從字串的末尾開始算起,注意,負數前面必須有一個空格, 以防止與${variable:-word}的變數的設定默認值語法混淆,這時還可以指定length,length可以是正值,也可以是負值(負值不能超過offset的長度),
$ foo="This string is long."
$ echo ${foo: -5}
long.
$ echo ${foo: -5:2}
lo
$ echo ${foo: -5:-2}
lon
??上面例子中,offset為-5,表示從倒數第5個字符開始截取,所以回傳long.,如果指定長度length為2,則回傳lo;如果length為-2,表示要排除從字串末尾開始的2個字符,所以回傳lon,
??3.搜索和替換
Bash 提供字串搜索和替換的多種方法,
??(1)字串頭部的模式匹配,
??以下兩種語法可以檢查字串開頭,是否匹配給定的模式,如果匹配成功,就洗掉匹配的部分,回傳剩下的部分,原始變數不會發生變化,
# 如果 pattern 匹配變數 variable 的開頭,
# 洗掉最短匹配(非貪婪匹配)的部分,回傳剩余部分
${variable#pattern}
# 如果 pattern 匹配變數 variable 的開頭,
# 洗掉最長匹配(貪婪匹配)的部分,回傳剩余部分
${variable##pattern}
上面兩種語法會洗掉變數字串開頭的匹配部分(將其替換為空),回傳剩下的部分,區別是一個是最短匹配(又稱非貪婪匹配),另一個是最長匹配(又稱貪婪匹配),
匹配模式pattern可以使用*、?、[]等通配符,
$ myPath=/home/cam/book/long.file.name
$ echo ${myPath#/*/}
cam/book/long.file.name
$ echo ${myPath##/*/}
long.file.name
??上面例子中,匹配的模式是//,其中可以匹配任意數量的字符,所以最短匹配是/home/,最長匹配是/home/cam/book/,
??下面寫法可以洗掉檔案路徑的目錄部分,只留下檔案名,
$ path=/home/cam/book/long.file.name
$ echo ${path##*/}
long.file.name
??上面例子中,模式*/匹配目錄部分,所以只回傳檔案名,
下面再看一個例子,
$ phone="555-456-1414"
$ echo ${phone#*-}
456-1414
$ echo ${phone##*-}
1414
??如果匹配不成功,則回傳原始字串,
$ phone="555-456-1414"
$ echo ${phone#444}
555-456-1414
上面例子中,原始字串里面無法匹配模式444,所以原樣回傳,
??如果要將頭部匹配的部分,替換成其他內容,采用下面的寫法,
# 模式必須出現在字串的開頭
${variable/#pattern/string}
# 示例
$ foo=JPG.JPG
$ echo ${foo/#JPG/jpg}
jpg.JPG
??上面例子中,被替換的JPG必須出現在字串頭部,所以回傳jpg.JPG,
??(2)字串尾部的模式匹配,
??以下兩種語法可以檢查字串結尾,是否匹配給定的模式,如果匹配成功,就洗掉匹配的部分,回傳剩下的部分,原始變數不會發生變化,
# 如果 pattern 匹配變數 variable 的結尾,
# 洗掉最短匹配(非貪婪匹配)的部分,回傳剩余部分
${variable%pattern}
# 如果 pattern 匹配變數 variable 的結尾,
# 洗掉最長匹配(貪婪匹配)的部分,回傳剩余部分
${variable%%pattern}
??上面兩種語法會洗掉變數字串結尾的匹配部分(將其替換為空),回傳剩下的部分,區別是一個是最短匹配(又稱非貪婪匹配),另一個是最長匹配(又稱貪婪匹配),
$ path=/home/cam/book/long.file.name
$ echo ${path%.*}
/home/cam/book/long.file
??注意:“%”是指從左往右遇到的最后一個pattern,如示例中的最后一個“ . ”符合,之后的內容均被 “ * ”通配符選中而洗掉,
$ echo ${path%%.*}
/home/cam/book/long
??而 “%%”是指從右往左遇到的第一個pattern,洗掉該pattern和之后的內容,如示例中被選中的洗掉內容就是.file.name,若我們該為 echo ${path%%a*} 則結果為/home/c
??上面例子中,匹配模式是.,其中可以匹配任意數量的字符,所以最短匹配是.name,最長匹配是.file.name,
??下面寫法可以洗掉路徑的檔案名部分,只留下目錄部分,
$ path=/home/cam/book/long.file.name
$ echo ${path%/*}
/home/cam/book
??上面例子中,模式/*匹配檔案名部分,所以只回傳目錄部分,
??下面的寫法可以替換檔案的后綴名,
$ file=foo.png
$ echo ${file%.png}.jpg
foo.jpg
??上面的例子將檔案的后綴名,從.png改成了.jpg,
??下面再看一個例子,
$ phone="555-456-1414"
$ echo ${phone%-*}
555-456
$ echo ${phone%%-*}
555
??如果匹配不成功,則回傳原始字串,
??如果要將尾部匹配的部分,替換成其他內容,采用下面的寫法,
# 模式必須出現在字串的結尾
${variable/%pattern/string}
# 示例
$ foo=JPG.JPG
$ echo ${foo/%JPG/jpg}
JPG.jpg
??上面例子中,被替換的JPG必須出現在字串尾部,所以回傳JPG.jpg,
(3)任意位置的模式匹配,
??以下兩種語法可以檢查字串內部,是否匹配給定的模式,如果匹配成功,就洗掉匹配的部分,換成其他的字串回傳,原始變數不會發生變化,
# 如果 pattern 匹配變數 variable 的一部分,
# 最長匹配(貪婪匹配)的那部分被 string 替換,但僅替換第一個匹配
${variable/pattern/string}
# 如果 pattern 匹配變數 variable 的一部分,
# 最長匹配(貪婪匹配)的那部分被 string 替換,所有匹配都替換
${variable//pattern/string}
??上面兩種語法都是最長匹配(貪婪匹配)下的替換,區別是前一個語法僅僅替換第一個匹配,后一個語法替換所有匹配,
$ path=/home/cam/foo/foo.name
$ echo ${path/foo/bar}
/home/cam/bar/foo.name
$ echo ${path//foo/bar}
/home/cam/bar/bar.name
??上面例子中,前一個命令只替換了第一個foo,后一個命令將兩個foo都替換了,
??下面的例子將分隔符從:換成換行符,
$ echo -e ${PATH//:/'\n'}
/usr/local/bin
/usr/bin
/bin
...
??上面例子中,echo命令的-e引數,表示將替換后的字串的\n字符,解釋為換行符,
??模式部分可以使用通配符,
$ phone="555-456-1414"
$ echo ${phone/5?4/-}
55-56-1414
??上面的例子將5-4替換成-,
??如果省略了string部分,那么就相當于匹配的部分替換成空字串,即洗掉匹配的部分,
$ path=/home/cam/foo/foo.name
$ echo ${path/.*/}
/home/cam/foo/foo
??上面例子中,第二個斜杠后面的string部分省略了,所以模式.*匹配的部分.name被洗掉后回傳,
??前面提到過,這個語法還有兩種擴展形式,
# 模式必須出現在字串的開頭
${variable/#pattern/string}
# 模式必須出現在字串的結尾
${variable/%pattern/string}
改變大小寫
??下面的語法可以改變變數的大小寫,
# 轉為大寫
${varname^^}
# 轉為小寫
${varname,,}
??下面是一個例子,
$ foo=heLLo
$ echo ${foo^^}
HELLO
$ echo ${foo,,}
hello
??變數
??注:教程來源于網道 Bash腳本,博主僅做個人學習的筆記,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/278968.html
標籤:其他
上一篇:外部網關協議----BGP及實驗
