在做shell批處理程序時候,經常會涉及到字符串相關操作。有很多命令語句,如:awk,sed都可以做字符串各種操作。 其實shell內置一系列操作符號,可以達到類似效果,大家知道,使用內部操作符會省略啟動外部程序等時間,因此速度會非常的快。
?
一、判斷讀取字符串值
表達式 含義
|
| ${var} | 變量var的值, 與$var相同 |
| ? | ? |
| ${var-DEFAULT} | 如果var沒有被聲明, 那么就以$DEFAULT作為其值 * |
| ${var:-DEFAULT} | 如果var沒有被聲明, 或者其值為空, 那么就以$DEFAULT作為其值 * |
| ? | ? |
| ${var=DEFAULT} | 如果var沒有被聲明, 那么就以$DEFAULT作為其值 * |
| ${var:=DEFAULT} | 如果var沒有被聲明, 或者其值為空, 那么就以$DEFAULT作為其值 * |
| ? | ? |
| ${var+OTHER} | 如果var聲明了, 那么其值就是$OTHER, 否則就為null字符串 |
| ${var:+OTHER} | 如果var被設置了, 那么其值就是$OTHER, 否則就為null字符串 |
| ? | ? |
| ${var?ERR_MSG} | 如果var沒被聲明, 那么就打印$ERR_MSG * |
| ${var:?ERR_MSG} | 如果var沒被設置, 那么就打印$ERR_MSG * |
| ? | ? |
| ${!varprefix*} | 匹配之前所有以varprefix開頭進行聲明的變量 |
| ${!varprefix@} | 匹配之前所有以varprefix開頭進行聲明的變量 |
加入了“*”? 不是意思是: 當然, 如果變量var已經被設置的話, 那么其值就是$var.
?
?
二、字符串操作(長度,讀取,替換)
表達式 含義
|
| ${#string} | $string的長度 |
| ? | ? |
| ${string:position} | 在$string中, 從位置$position開始提取子串 |
| ${string:position:length} | 在$string中, 從位置$position開始提取長度為$length的子串 |
| ? | ? |
| ${string#substring} | 從變量$string的開頭, 刪除最短匹配$substring的子串 |
| ${string##substring} | 從變量$string的開頭, 刪除最長匹配$substring的子串 |
| ${string%substring} | 從變量$string的結尾, 刪除最短匹配$substring的子串 |
| ${string%%substring} | 從變量$string的結尾, 刪除最長匹配$substring的子串 |
| ? | ? |
| ${string/substring/replacement} | 使用$replacement, 來代替第一個匹配的$substring |
| ${string//substring/replacement} | 使用$replacement, 代替所有匹配的$substring |
| ${string/#substring/replacement} | 如果$string的前綴匹配$substring, 那么就用$replacement來代替匹配到的$substring |
| ${string/%substring/replacement} | 如果$string的后綴匹配$substring, 那么就用$replacement來代替匹配到的$substring |
| ? | ? |
說明:"*?$substring”可以是一個正則表達式.
?
?實例:
?
讀取:
Java代碼??
$?echo?${abc-'ok'}?? ok?? $?echo?$abc?? $?echo?${abc='ok'}?? ok?? $?echo?$abc?? ok?? ?? #如果abc?沒有聲明“="?還會給abc賦值。?? $?var1=11;var2=12;var3=?? $?echo?${!v@}????????????? var1?var2?var3?? $?echo?${!v*}?? var1?var2?var3?? ?? #${!varprefix*}與${!varprefix@}相似,可以通過變量名前綴字符,搜索已經定義的變量,無論是否為空值。?? ?
1,取得字符串長度
C代碼??
string=abc12342341???????????? echo?${#string}??????????????? expr?length?$string??????????? expr?"$string"?:?".*"????????? ?
?2,字符串所在位置
C代碼??
expr?index?$string?'123'?????? ? C代碼??
str="abc"?? expr?index?$str?"a"??#?1?? expr?index?$str?"b"??#?2?? expr?index?$str?"x"??#?0?? expr?index?$str?""???#?0??? ?
這個方法讓我想起來了js的indexOf,各種語言對字符串的操作方法大方向都差不多,如果有語言基礎的話,學習shell會很快的。
?
3,從字符串開頭到子串的最大長度
C代碼??
expr?match?$string?'abc.*3'??? ?
個人覺得這個函數的用處不大,為什么要從開頭開始呢。
?
4,字符串截取
C代碼??
echo?${string:4}???????? echo?${string:3:3}?????? echo?${string:3:6}?????? echo?${string:?-4}?????? echo?${string:(-4)}????? expr?substr?$string?3?3????? ?
C代碼??
str="abcdef"?? expr?substr?"$str"?1?3??#?從第一個位置開始取3個字符,?abc?? expr?substr?"$str"?2?5??#?從第二個位置開始取5個字符,?bcdef??? expr?substr?"$str"?4?5??#?從第四個位置開始取5個字符,?def?? ?? echo?${str:2}???????????#?從第二個位置開始提取字符串,?bcdef?? echo?${str:2:3}?????????#?從第二個位置開始提取3個字符,?bcd?? echo?${str:(-6):5}????????#?從倒數第二個位置向左提取字符串,?abcde?? echo?${str:(-4):3}??????#?從倒數第二個位置向左提取6個字符,?cde?? ?
上面的方法讓我想起了,php的substr函數,后面截取的規則是一樣的。
?
5,匹配顯示內容
C代碼??
?? expr?match?$string?'\([a-c]*[0-9]*\)'???? expr?$string?:?'\([a-c]*[0-9]\)'????????? expr?$string?:?'.*\([0-9][0-9][0-9]\)'??? ?
這里括號的用法,是不是根其他的括號用法有相似之處呢,
?
6,截取不匹配的內容
C代碼??
echo?${string#a*3}??????? echo?${string#c*3}??????? echo?${string#*c1*3}????? echo?${string##a*3}?????? echo?${string%3*1}??????? echo?${string%%3*1}?????? ? C代碼??
str="abbc,def,ghi,abcjkl"?? echo?${str#a*c}?????#?輸出,def,ghi,abcjkl??一個井號(#)?表示從左邊截取掉最短的匹配?(這里把abbc字串去掉)?? echo?${str##a*c}????#?輸出jkl,?????????????兩個井號(##)?表示從左邊截取掉最長的匹配?(這里把abbc,def,ghi,abc字串去掉)?? echo?${str#"a*c"}???#?輸出abbc,def,ghi,abcjkl?因為str中沒有"a*c"子串?? echo?${str##"a*c"}??#?輸出abbc,def,ghi,abcjkl?同理?? echo?${str#*a*c*}???#?空?? echo?${str##*a*c*}??#?空?? echo?${str#d*f)?????#?輸出abbc,def,ghi,abcjkl,??? echo?${str#*d*f}????#?輸出,ghi,abcjkl????? ?? echo?${str%a*l}?????#?abbc,def,ghi??一個百分號(%)表示從右邊截取最短的匹配??? echo?${str%%b*l}????#?a?????????????兩個百分號表示(%%)表示從右邊截取最長的匹配?? echo?${str%a*c}?????#?abbc,def,ghi,abcjkl???? ?
這里要注意,必須從字符串的第一個字符開始,或者從最后一個開始,可以這樣記憶, 井號(#)通常用于表示一個數字,它是放在前面的;百分號(%)卸載數字的后面; 或者這樣記憶,在鍵盤布局中,井號(#)總是位于百分號(%)的左邊(即前面)? 。
?
7,匹配并且替換
C代碼??
echo?${string/23/bb}????? echo?${string?? echo?${string/#abc/bb}??? echo?${string/%41/bb}???? ?
C代碼??
str="apple,?tree,?apple?tree"?? echo?${str/apple/APPLE}???#?替換第一次出現的apple?? echo?${str?? ?? echo?${str/#apple/APPLE}??#?如果字符串str以apple開頭,則用APPLE替換它?? echo?${str/%apple/APPLE}??#?如果字符串str以apple結尾,則用APPLE替換它?? ? C代碼??
$?test='c:/windows/boot.ini'?? $?echo?${test/\?? c:\windows/boot.ini?? $?echo?${test?? c:\windows\boot.ini?? ?? #${變量/查找/替換值}?一個“/”表示替換第一個,”//”表示替換所有,當查找中出現了:”/”請加轉義符”\/”表示。?? ?
8. 比較
C代碼??
[[?"a.txt"?==?a*?]]????????#?邏輯真?(pattern?matching)?? [[?"a.txt"?=~?.*\.txt?]]???#?邏輯真?(regex?matching)?? [[?"abc"?==?"abc"?]]???????#?邏輯真?(string?comparision)??? [[?"11"?<?"2"?]]???????????#?邏輯真?(string?comparision),?按ascii值比較?? ?
9. 連接
C代碼??
s1="hello"?? s2="world"?? echo?${s1}${s2}???#?當然這樣寫?$s1$s2?也行,但最好加上大括號??
10. 字符串刪除 Java代碼??
$?test='c:/windows/boot.ini'?? $?echo?${test#/}?? c:/windows/boot.ini?? $?echo?${test#*/}?? windows/boot.ini?? $?echo?${test##*/}?? boot.ini?? ?? $?echo?${test%? ? ? ? ? ? },${test%/*}?分別是得到文件名,或者目錄地址最簡單方法。??? ?
總結
以上是生活随笔為你收集整理的linux shell 字符串操作详解 (长度,读取,替换,截取,连接,对比,删除,位置 )的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。