Appearance
参数扩展
参数扩展(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"