Shell 中使用 ${} 进行字符串截取

Shell 中使用 ${} 进行字符串截取

在 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
# 若已知路径深度,也可用截取(不推荐)

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注