在 Bash(及其他 POSIX 兼容 shell)中,${} 不仅用于变量引用,还支持丰富的**参数扩展(Parameter Expansion)**功能,可用于字符串截取、替换、默认值设置等操作。其中,字符串截取是最常用的功能之一。
一、按位置和长度截取(基于索引)
${variable:offset}
${variable:offset:length}
variable:要操作的字符串变量;offset:起始位置(从 0 开始);length:截取长度(可选);- 支持负数偏移(需加空格或括号,见下文)。
⚠️ 注意:该语法是 Bash 特有,部分 POSIX shell(如 dash)不支持。
1.1、正向截取(从左到右)
从指定位置截取到末尾
str="hello world"
echo ${str:6} # 输出: world
- 从索引
6(第7个字符)开始,取到结尾。
从指定位置截取固定长度
str="hello world"
echo ${str:0:5} # 输出: hello
echo ${str:6:5} # 输出: world
- 从索引
0开始,取5个字符。
1.2、反向截取(从右到左,使用负数)
Bash 支持负数偏移,表示从字符串末尾开始计算。
❗ 重要:负数前必须加空格或用括号,否则会被解析为默认值语法
${var:-value}。
正确写法:
str="hello world"
# 方法1:负数前加空格
echo ${str: -5} # 输出: world
# 方法2:用括号包裹
echo ${str:(-5)} # 输出: world
# 截取末尾5个字符中的前3个
echo ${str: -5:3} # 输出: wor
echo ${str:(-5):3} # 输出: wor
错误写法(会出错或结果不符预期):
echo ${str:-5} # 错!这是“若 str 为空则用 -5”的默认值语法
二、按模式匹配截取(基于通配符)
使用 #(前缀)和 %(后缀)操作符,配合通配符(如 *)进行模式匹配删除。
| 语法 | 作用 | 匹配方式 |
|---|---|---|
${var#pattern} | 删除最短匹配的前缀 | 非贪婪 |
${var##pattern} | 删除最长匹配的前缀 | 贪婪 |
${var%pattern} | 删除最短匹配的后缀 | 非贪婪 |
${var%%pattern} | 删除最长匹配的后缀 | 贪婪 |
2.1、获取文件扩展名
filename="document.pdf"
ext=${filename##*.} # => pdf (删除最长匹配的 *. 前缀)
# 或用截取(需知道长度)
ext=${filename: -3} # => pdf (假设扩展名3位)
💡 更通用的方式是用
${var##*.},但截取适用于固定长度场景。
2.2、去掉路径,只留文件名
path="/home/user/file.txt"
basename=${path##*/} # => file.txt
# 若已知路径深度,也可用截取(不推荐)


发表回复