(轉)shell 編程:冒號 后面跟 等號,加號,減號,問號的意義


原文:https://handerfly.github.io/shell/2019/04/03/shell%E7%BC%96%E7%A8%8B%E5%86%92%E5%8F%B7%E5%8A%A0-%E7%AD%89%E5%8F%B7-%E5%8A%A0%E5%8F%B7-%E5%87%8F%E5%8F%B7-%E9%97%AE%E5%8F%B7/

shell 編程:冒號 后面跟 等號,加號,減號,問號的意義

缺省值(:-)

${var:-string} 若變量var為空或者未定義,則用在命令行中用string來替換${var:-string} 否則變量var不為空時,則用變量var的值來替換${var:-string}

$ COMPANY=
$ printf "%s\n" "${COMPANY:-Unknown Company}"
Unknown Company
$ echo $COMPANY

變量的實際值保持不變。

指定缺省值(:=)

如果變量后面跟着冒號和等號,則給空變量指定一個缺省值。

$ printf "%s\n" "${COMPANY:=Nightlight Inc.}"
Nightlight Inc.
$ printf "%s\n" "${COMPANY}”
Nightlight Inc.

變量的實際值已經改變了。 比較${var:-string}和${var:=string} 后者發現$var為空時,把string賦值給了var
后者是一種賦值默認值的常見做法

變量是否存在檢查(:?)

替換規則:若變量var不為空,則用變量var的值來替換${var:?string}
若變量var為空,則把string輸出到標准錯誤中,並從腳本中退出。
可利用此特性來檢查是否設置了變量的值

根據變量是否存在,顯示不同的信息。信息不是必選的。

printf "Company is %s\n" "${COMPANY:?Error: Company has notbeen defined—aborting}"

覆蓋缺省值(:+)

${var:+string} 規則和${var:-string},${var:=string}的完全相反 即只有當var不是空的時候才替換成string,若var為空時則不替換或者說是替換成變量var的值,即空值

$ COMPANY="Nightlight Inc."
$ printf "%s\n" "${COMPANY:+Company has been overridden}"
Company has been overridden

替換部分字符串(:n)

如果變量后面跟着一個冒號和數字,則返回該數字開始的一個子字符串,如果后面還跟着一個冒號和數字。則第一個數字表示開始的字符,后面數字表示字符的長度。

$ printf "%s\n" "${COMPANY:5}"
light Inc.
$ printf "%s\n" "${COMPANY:5:5}"
light

根據模板刪除字串(%,#,%%,##) #刪除左邊,%刪除右邊 如果變量后面跟着井號,則返回匹配模板被刪除后的字串。一個井號為最小可能性的匹配,兩個井號為自大可能性的匹配。表達式返回模板右邊的字符。

$ COMPANY="Nightlight Inc."
$ printf "%s\n" "${COMPANY#Ni*}"
ghtlight Inc.
$ printf "%s\n" "${COMPANY##Ni*}"

$ printf "%s\n" "${COMPANY##*t}"
Inc.
$ printf "%s\n" "${COMPANY#*t}"
light Inc.

#使用百分號,表達式返回模板左邊的字符
$ printf "%s\n" "${COMPANY%t*}"
Nightligh
$ printf "%s\n" "${COMPANY%%t*}"
Nigh

案例: 獲取文件名和后綴名

$ f=file.tar.gz
$ echo ${f##*.}
gz
$ echo ${f%%.*}
file

#假設我們定義了一個變量為:
file=/dir1/dir2/dir3/my.file.txt

#可以用${ }分別替換得到不同的值:
${file#*/}:刪掉第一個 / 及其左邊的字符串:dir1/dir2/dir3/my.file.txt
${file##*/}:刪掉最后一個 /  及其左邊的字符串:my.file.txt
${file#*.}:刪掉第一個 .  及其左邊的字符串:file.txt
${file##*.}:刪掉最后一個 .  及其左邊的字符串:txt
${file%/*}:刪掉最后一個  /  及其右邊的字符串:/dir1/dir2/dir3
${file%%/*}:刪掉第一個 /  及其右邊的字符串:(空值)
${file%.*}:刪掉最后一個  .  及其右邊的字符串:/dir1/dir2/dir3/my.file
${file%%.*}:刪掉第一個  .   及其右邊的字符串:/dir1/dir2/dir3/my

記憶的方法為: #是 去掉左邊(鍵盤上#在 $ 的左邊) %是去掉右邊(鍵盤上% 在$ 的右邊) 單一符號是最小匹配;兩個符號是最大匹配

使用模板進行子字符串的替換(//)

如果變量后只有一個斜杠,則兩個斜杠中間的字符串是要被替換的字符串,而第二個斜杠后面的字符串是要替換的字符串。如果變量后面跟着兩個斜杠,則所有出現在兩個斜杠中間的字符都要被替換為最后一個斜杠后面的字符。

$ printf "%s\n" "${COMPANY/Inc./Incorporated}"
Nightlight Incorporated
$ printf "You are the I in %s\n" "${COMPANY//i/I}"
You are the I in NIghtlIght Inc.

如果模板以#號開始,則匹配以模板開始的字符,如果模板以%號結尾(在centos7上測試不生效),則匹配以模板結尾的字符。

$ COMPANY="NightLight Night Lighting Inc."
$ printf "%s\n" "$COMPANY"
NightLight Night Lighting Inc.
$ printf "%s" "${COMPANY//Night/NIGHT}"
NIGHTLight NIGHT Lighting Inc.
$ printf "%s" "${COMPANY//#Night/NIGHT}"
NIGHTLight Night Lighting Inc.

如果沒有指定新的值,則匹配的字符會被刪除。

$ COMPANY="Nightlight Inc."
$ printf "%s\n" "${COMPANY/light}"
Night Inc.

也可以使用范圍符號。例如:刪除所有字符串中的標點符號,使用范圍[:punct:]。

$ printf "%s" "${COMPANY//[[:punct:]]}"
Nightlight Inc

使用號或@符號替換變量會替換shell腳本中所有的參數,同樣,在數組中使用號或@符號也會替換數組中的所有元素


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM