三大核心語法對照
| 語法 | 名稱 | 功能 | 典型用途 |
${var} | 變量擴展 | 明確界定變量名稱邊界、字串操作 | 變量連接、子字串截取、預設值 |
$(cmd) | 命令替換 | 執行命令並將標準輸出作為字串 | 捕獲命令結果、動態參數、管線替代 |
$((expr)) | 算術運算 | 整數運算、邏輯判斷 | 計數器、數學計算、位元運算 |
${} 變量擴展進階
界定變量名稱
bak_path="/mnt/bak"
# 錯誤:系統尋找 $bak_pathbak 變量
cp /etc/passwd $bak_pathbak
# 正確:明確界定
cp /etc/passwd ${bak_path}bak
# 或
cp /etc/passwd ${bak_path}/bak
字串截取與處理
str="hello_world"
# 從索引 1 開始取 2 個字元(索引從 0 起)
echo ${str:1:2} # 輸出 "el"
# 移除前綴(最短匹配)
echo ${str#*_} # 輸出 "world"
# 移除前綴(最長匹配)
echo ${str##*_} # 輸出 "world"
# 移除後綴(最短匹配)
echo ${str%_*} # 輸出 "hello"
# 移除後綴(最長匹配)
echo ${str%%_*} # 輸出 "hello"
# 替換(首次)
echo ${str/_/-} # 輸出 "hello-world"
# 替換(全部)
echo ${str//_/-} # 輸出 "hello-world"
# 預設值:變量未設定或為空時使用
echo ${undefined:-"default"} # 輸出 "default"
# 賦值預設值
echo ${undefined:="new"} # 設定並輸出 "new"
$( ) 命令替換實戰
捕獲命令輸出作為參數
# 終止特定進程
kill -9 $(pgrep -f tomcat)
# 動態建構檔案名
backup_file="backup_$(date +%Y%m%d_%H%M%S).tar.gz"
tar czf "$backup_file" /data
# 巢狀替換
echo "Today is $(date +%A), week $(date +%V) of $(date +%Y)"
替代反引號 ` `
# 舊寫法(不支援巢狀)
result=`grep pattern file | wc -l`
# 新寫法(支援巢狀、可讀性佳)
result=$(grep pattern file | wc -l)
$(( )) 算術運算
基本運算
echo $(( 25 * 125 )) # 3125
echo $(( 10 + 5 * 3 )) # 25(遵循運算子優先序)
echo $(( 2**8 )) # 256(冪次)
echo $(( 17 % 5 )) # 2(取餘)
變量運算(無需 $ 符號)
count=10
step=3
echo $(( count + step )) # 13
echo $(( count++ )) # 10(後置遞增)
echo $(( ++count )) # 12(前置遞增)
邏輯與位元運算
# 比較運算(真=1,假=0)
echo $(( 5 > 3 )) # 1
echo $(( 5 == 3 )) # 0
# 位元運算
echo $(( 12 & 10 )) # 8 (1100 & 1010 = 1000)
echo $(( 12 | 10 )) # 14 (1100 | 1010 = 1110)
echo $(( 12 ^ 10 )) # 6 (1100 ^ 1010 = 0110)
echo $(( ~12 )) # -13(補數)
綜合範例:批次重命名
for f in *.jpg; do
# 取得不含副檔名的基礎名稱
base=${f%.jpg}
# 取得日期字串
date_str=$(date -r "$f" +%Y%m%d)
# 新檔名
mv "$f" "${date_str}_${base}.jpg"
done