Shell 批次處理常需字串操作。雖可用 awk、sed,但 Shell 內建操作符省去啟動外部程序開銷,速度極快。本文系統整理內建字串操作語法與效能比較。
| 表示式 | 含義 |
|---|---|
| ${var} | 變數值,同 $var |
| ${var-DEFAULT} | var 未宣告則用 DEFAULT |
| ${var:-DEFAULT} | var 未宣告或為空則用 DEFAULT |
| ${var=DEFAULT} | var 未宣告則設為 DEFAULT 並賦值 |
| ${var:=DEFAULT} | var 未宣告或為空則設為 DEFAULT 並賦值 |
| ${var+OTHER} | var 已宣告則值為 OTHER,否則空字串 |
| ${var:+OTHER} | var 已設定則值為 OTHER,否則空字串 |
| ${var?ERR_MSG} | var 未宣告則印出 ERR_MSG |
| ${var:?ERR_MSG} | var 未設定則印出 ERR_MSG |
| ${!varprefix*} | 列出所有以 varprefix 開頭的已宣告變數 |
| ${!varprefix@} | 同上 |
echo ${abc-'ok'} # ok(abc 未宣告)
echo ${abc='ok'} # ok 且 abc 被賦值
var1=11; var2=12; var3=
echo ${!v*} # var1 var2 var3(含空值)
| 表示式 | 含義 |
|---|---|
| ${#string} | 字串長度 |
| ${string:position} | 從 position 起擷取子字串 |
| ${string:position:length} | 從 position 起擷取 length 長度子字串 |
| ${string#substring} | 從開頭刪除最短符合 substring |
| ${string##substring} | 從開頭刪除最長符合 substring |
| ${string%substring} | 從結尾刪除最短符合 substring |
| ${string%%substring} | 從結尾刪除最長符合 substring |
| ${string/substring/replacement} | 替換第一個符合 substring |
| ${string//substring/replacement} | 替換所有符合 substring |
| ${string/#substring/replacement} | 前綴符合則替換 |
| ${string/%substring/replacement} | 後綴符合則替換 |
注意:substring 可為正則表示式。
# 長度
test='I love china'
echo ${#test} # 12
# 擷取
echo ${test:5} # e china
echo ${test:5:10} # e china
# 刪除(取檔名/目錄最常用)
test='c:/windows/boot.ini'
echo ${test##*/} # boot.ini(檔名)
echo ${test%/*} # c:/windows(目錄)
# 替換
echo ${test/\//\\} # c:\windows/boot.ini(首個)
echo ${test//\//\\} # c:\windows\boot.ini(全部)
test='c:/windows/boot.ini'
# 內建 ${#var}
time for i in $(seq 10000); do a=${#test}; done
real 0m0.173s
# 外部 expr
time for i in $(seq 10000); do a=$(expr length $test); done
real 0m9.734s
結論:內建操作符比呼叫外部指令 快上百倍。同理 awk、sed 亦有同樣落差。Shell 程式設計應優先使用內建操作符或函數。