Skip to content

参数扩展

参数扩展(Parameter Expansion)是 Shell 中处理变量的强大机制,提供默认值、字符串截取、替换等功能。

基本引用

bash
name="world"
echo ${name}       # world(等同 $name)
echo "${name}!"    # world!(用于避免歧义)

默认值处理

${var:-default} — 变量为空时使用默认值

bash
name=""
echo ${name:-"张三"}   # 张三(name 为空,使用默认值)
name="李四"
echo ${name:-"张三"}   # 李四(name 非空,使用原值)

${var:=default} — 变量为空时赋值并返回

bash
echo ${unset_var:="默认值"}   # 默认值
echo $unset_var               # 默认值(变量已被赋值)

${var:+value} — 变量非空时返回 value

bash
name="张三"
echo ${name:+"已设置"}   # 已设置
empty=""
echo ${empty:+"已设置"}  # (空,不输出)

${var:?message} — 变量为空时报错退出

bash
#!/bin/bash
# 强制要求变量必须设置
: ${REQUIRED_VAR:?"错误:REQUIRED_VAR 未设置"}

字符串长度

bash
str="Hello World"
echo ${#str}   # 11

arr=(a b c d)
echo ${#arr[@]}   # 4(数组元素数量)

子字符串截取

${var:offset} — 从偏移量开始截取到末尾

bash
str="Hello World"
echo ${str:6}      # World
echo ${str:0:5}    # Hello(从 0 开始取 5 个)
echo ${str:6:3}    # Wor(从 6 开始取 3 个)
echo ${str: -5}    # World(从倒数第 5 个开始,注意空格)

数组切片

bash
arr=(a b c d e)
echo ${arr[@]:1:3}   # b c d(从索引 1 取 3 个)

前缀删除

${var#pattern} — 删除最短前缀匹配

bash
path="/usr/local/bin/bash"
echo ${path#/usr}         # /local/bin/bash
echo ${path#*/}           # usr/local/bin/bash(删除第一个 / 前的内容)

${var##pattern} — 删除最长前缀匹配(贪婪)

bash
path="/usr/local/bin/bash"
echo ${path##*/}    # bash(获取文件名,等效 basename)

后缀删除

${var%pattern} — 删除最短后缀匹配

bash
file="document.tar.gz"
echo ${file%.*}     # document.tar(删除最后一个扩展名)

${var%%pattern} — 删除最长后缀匹配(贪婪)

bash
file="document.tar.gz"
echo ${file%%.*}    # document(删除所有扩展名)

字符串替换

${var/pattern/replacement} — 替换第一个匹配

bash
str="hello hello world"
echo ${str/hello/hi}    # hi hello world

${var//pattern/replacement} — 替换所有匹配

bash
str="hello hello world"
echo ${str//hello/hi}   # hi hi world

${var/#pattern/replacement} — 替换前缀

bash
str="hello world"
echo ${str/#hello/hi}   # hi world

${var/%pattern/replacement} — 替换后缀

bash
str="hello world"
echo ${str/%world/there}   # hello there

大小写转换(Bash 4+)

bash
str="Hello World"

echo ${str,,}    # hello world(全部小写)
echo ${str^^}    # HELLO WORLD(全部大写)
echo ${str,}     # hELLO WORLD → hello World(首字母小写)
echo ${str^}     # Hello World(首字母大写)

间接引用

bash
var_name="PATH"
echo ${!var_name}   # 输出 $PATH 的值

实用示例

bash
#!/bin/bash

# 获取文件名(不含路径)
filepath="/home/user/docs/readme.md"
filename=${filepath##*/}
echo "文件名:$filename"   # readme.md

# 获取不含扩展名的文件名
basename=${filename%.*}
echo "基础名:$basename"   # readme

# 获取扩展名
ext=${filename##*.}
echo "扩展名:$ext"   # md

# 获取目录路径
dirpath=${filepath%/*}
echo "目录:$dirpath"   # /home/user/docs

# 路径中的空格替换为下划线
path_with_spaces="my file name.txt"
safe_path=${path_with_spaces// /_}
echo "$safe_path"   # my_file_name.txt

# 提供脚本默认参数
output_dir="${1:-/tmp/output}"
log_level="${LOG_LEVEL:-info}"
echo "输出目录:$output_dir,日志级别:$log_level"