在 bash 中,一般使用 ${parameter}
表達式來獲取 parameter 變量的值,這是一種參數擴展 (parameter expansion)。
Bash 還提供了其餘形式的參數擴展,能夠對變量值作一些處理,起到操做字符串的效果。例如:正則表達式
${parameter^^pattern}
把 parameter 變量值中匹配 pattern 模式字符的小寫字母轉成大寫。${parameter,,pattern}
把 parameter 變量值中匹配 pattern 模式字符的大寫字母轉成小寫。${parameter/pattern/string}
把 parameter 變量值中匹配 pattern 模式的部分替換爲 string 字符串。注意:這些表達式都不會修改 parameter 自身的變量值,它們只是基於 parameter 變量值擴展獲得新的值。
若是要保存這些值,須要賦值給具體的變量。bash
查看 man bash 的 Parameter Expansion 小節,就能看到相關說明。具體舉例說明以下。app
${parameter^^pattern} 和 ${parameter,,pattern}
查看 man bash 對 ${parameter^pattern}, ${parameter^^pattern}, ${parameter,pattern}, ${parameter,,pattern}
的說明以下:this
Case modification.
This expansion modifies the case of alphabetic characters in parameter. The pattern is expanded to produce a pattern just as in pathname expansion.The ^ operator converts lowercase letters matching pattern to uppercase; the , operator converts matching uppercase letters to lowercase.
The ^^ and ,, expansions convert each matched character in the expanded value; the ^ and , expansions match and convert only the first character in the expanded value. codeIf pattern is omitted, it is treated like a ?, which matches every character. orm
If parameter is @ or *, the case modification operation is applied to each positional parameter in turn, and the expansion is the resultant list.
If parameter is an array variable subscripted with @ or *, the case modification operation is applied to each member of the array in turn, and the expansion is the resultant list.ip
即,這四個表達式會在 parameter 變量值中匹配 pattern 模式,並對匹配的字符進行大小寫轉換:字符串
^
操做符把小寫字母轉換爲大寫,且只轉換開頭的第一個字符,
操做符把大寫字母轉換爲小寫,且只轉換開頭的第一個字符^^
操做符把小寫字母轉換爲大寫,會轉換每個匹配的字符,,
操做符把大寫字母轉換爲小寫,會轉換每個匹配的字符這裏的 pattern 模式可使用通配符進行擴展,注意不是用正則表達式。string
注意:^
和 ,
不是轉換第一個匹配到的字符,而是隻轉換 parameter 變量值的首字符。
所給的 pattern 模式必須和 parameter 變量值的首字符匹配纔會轉換,不會轉換字符串中間的字符。it
具體舉例說明以下:
$ value="This Is a Test String." $ echo ${value^t} This Is a Test String. $ echo ${value^^t} This Is a TesT STring. $ echo ${value,T} this Is a Test String. $ echo ${value,,T} this Is a test String.
能夠看到,使用 ${value^t}
不會把 value 變量值中間小寫的 t
字符換行爲大寫。
由於這個表達式只匹配和轉換 value 變量值的首字符,value 變量值並非以小寫字母 t
開頭,不作轉換。
而 ${value^^t}
表達式會匹配 value 變量值中的每個小寫字母 t
,並轉換爲大寫。
因此輸出結果裏面再也不有小寫的 t
字符。
相似的,${value,T}
表示把 value 變量值開頭的大寫 T
轉換爲小寫的 t
。 ${value,,T}
表示把 value 變量值全部的大寫 T
轉換爲小寫的 t
。
若是省略 pattern 模式,則表示匹配任意字符,但並不表示會轉換全部字符,^
和 ,
操做符仍是隻轉換首字符。
以上面的 value 變量值舉例以下:
$ echo ${value^} This Is a Test String. $ echo ${value^^} THIS IS A TEST STRING. $ echo ${value,} this Is a Test String. $ echo ${value,,} this is a test string.
能夠看到,${value^}
只會把 value 變量值首字符變成大寫,因爲本來就是大寫,因此輸出結果跟 value 值同樣。 ${value^^}
把全部字符都轉換爲大寫。 ${value,}
把 value 變量值首字符變成小寫。 ${value,,}
把全部字符都轉換爲小寫。
注意:若是要匹配多個字符,要用方括號 []
把字符串括起來,進行 pathname expansion,纔會獲得多個可匹配的字符。
直接把 pattern 模式寫成字符串並不能匹配該字符串中的每個字符。
以上面的 value 變量值舉例以下:
$ echo ${value,TI} This Is a Test String. $ echo ${value,,TI} This Is a Test String. $ echo ${value,,[TI]} this is a test String. $ echo ${value,[TI]} this Is a Test String.
能夠看到,當所給模式寫爲 TI
時,不管是使用 ,
仍是 ,,
,都不能把大寫的 T
和 I
轉換爲小寫。 ${value,TI}
甚至都不能轉換開頭的 T
字符。
而寫爲 ${value,,[TI]}
就會把全部大寫的 T
和 I
都轉換爲小寫。 [TI]
就是 pathname expansion 的一種寫法,表示匹配方括號 []
裏面的每個字符。
基於字符匹配,不是基於字符串匹配。
寫爲 ${value,[TI]}
表示把首字符 T
或者首字符 I
轉換爲小寫,只匹配首字符。
關於 pathname expansion 的具體寫法能夠查看 man bash 的 Pathname Expansion 部分。
最多見的就是用 *
通配符匹配零個或多個任意字符,用 ?
匹配任意單個字符。
上面說明中提到,若是省略 pattern 模式,就至關於寫爲 ?
。
即 ${parameter^^}
等價於 ${parameter^^?}
。
${parameter/pattern/string}
查看 man bash 對 ${parameter/pattern/string}
的說明以下:
Pattern substitution.
The pattern is expanded to produce a pattern just as in pathname expansion. Parameter is expanded and the longest match of pattern against its value is replaced with string.If pattern begins with /, all matches of pattern are replaced with string. Normally only the first match is replaced. If pattern begins with #, it must match at the beginning of the expanded value of parameter.
If pattern begins with %, it must match at the end of the expanded value of parameter.If string is null, matches of pattern are deleted and the / following pattern may be omitted.
If parameter is @ or *, the substitution operation is applied to each positional parameter in turn, and the expansion is the resultant list.
If parameter is an array variable subscripted with @ or *, the substitution operation is applied to each member of the array in turn, and the expansion is the resultant list.
即,${parameter/pattern/string}
表達式能夠替換 parameter 變量值的字符串。
所給的 pattern 模式會按照文件名擴展 (pathname expansion) 的方式來擴展,而後對 parameter 變量值進行擴展。
其值中最長匹配 pattern 的部分會被替換成 string 指定的字符串。
若是 pattern 模式開始於 /
,全部匹配 pattern 模式的地方都被替換成 string 字符串。
一般僅僅替換第一個匹配的地方。
若是 pattern 模式開始於 #
,它必須從頭開始匹配 parameter 變量值。
若是 pattern 模式開始於 %
,它必須從後往前匹配 parameter 變量值。
若是 string 字符串是空,匹配 pattern 模式的地方會被刪除,且跟在 pattern 模式以後的 /
字符能夠省略。
具體舉例說明以下:
$ value="This is a test string. This is a new test" $ echo ${value/test/TEST} This is a TEST string. This is a new test $ echo ${value//test/TEST} This is a TEST string. This is a new TEST $ echo ${value/#test/TEST} This is a test string. This is a new test $ echo ${value/#This/THIS} THIS is a test string. This is a new test $ echo ${value/%test/TEST} This is a test string. This is a new TEST $ echo ${value/test} This is a string. This is a new test $ echo ${value//test} This is a string. This is a new
能夠看到,在 ${value/test/TEST}
表達式中,value 變量值是要被替換的原始字符串。
中間的 test 是要被替換的模式,且只替換第一個出現的 "test" 字符串,不會替換全部的 "test" 字符串。
後面的 TEST 是替換以後的內容。
最終輸出的結果是把 value 變量值中的第一個 "test" 字符串替換成了 "TEST",第二個 "test" 字符串沒有被替換。
${value//test/TEST}
表達式的 "/test" 模式以 /
開頭,表示替換全部出現的 "test" 字符串。
輸出結果全部的 "test" 字符串都替換成了 "TEST"。
${value/#test/TEST}
表達式的 "#test" 模式以 #
開頭,表示要從 value 變量值的第一個字符開始匹配。
因爲 value 變量值不是以 "test" 開頭,因此匹配不到,並無作替換。
要使用 ${value/#This/THIS}
來把 value 變量值開頭的 "This" 替換成 "THIS"。 ${value/%test/TEST}
表達式的狀況相似,要求從 value 變量值的末尾往前匹配 "test" 字符串。
這二者都是從最後一個字符往前開始匹配。
${value/test}
表達式沒有提供替換後的 string 參數,表示從 value 變量值中刪除第一個出現的 "test" 字符串。 ${value//test}
表達式的 "/test" 模式以 /
開頭,表示從 value 變量值中刪除全部出現的 "test" 字符串。
上面提到 "最長匹配" 部分會被替換。
所謂的 "最長匹配" 是指被 pattern 模式括起來的最長部分。
常見於用通配符匹配多個字符造成嵌套的狀況。
具體舉例以下:
$ value="This is a |test string|new test|, check it" $ echo ${value/|*|/NEW STRING} This is a NEW STRING, check it $ echo ${value/|*|} This is a , check it
能夠看到,所給的匹配模式是 |*|
。使用 *
通配符來匹配在兩個 |
之間的任意字符串。
在所給的 value 變量值裏面,"|test string|"、"|test string|new test|" 這兩種形式都匹配這個模式。
實際被替換的是最後一種,也就是最長匹配。
因爲該模式沒有以 /
開頭,只處理第一個匹配的地方,因此 "|new test|" 不會被匹配到。
即,當 pattern 模式的擴展結果是不定長的字符串時,它會有一個前綴部分、中間變長部分、後綴部分。
那麼最長匹配是從前綴部分開始匹配,一直到最後一個匹配的後綴部分爲止,而不是遇到第一個匹配的後綴部分就中止。
中間變長部分能夠包含多個前綴部分和後綴部分。
下面再舉例說明以下:
$ value="This is a test string, first check it" $ echo ${value/t*st} This is a check it
能夠看到,在所給的 value 變量值裏面,t*st
模式的後綴部分 "st" 匹配到了 "first" 字符串後面的 "st"。 而不是匹配到 "test" 字符串的 "st"。 最終結果取最長匹配的部分。