平时写Shell脚本时,处理文本是家常便饭。比如从日志里提取时间戳、从文件名中拿后缀、或者拆分路径和文件名,这些都离不开字符串截取。掌握几种常用的Shell字符串截取方法,能省下不少awk或sed的功夫。
使用${}内置语法截取
Shell本身提供了强大的变量扩展功能,不用调用外部命令就能完成大多数截取任务。
假设有一个变量:
filename="report_20241001.pdf"
想取出文件名中的日期部分,可以这样操作:
# 从第8个字符开始,取8位
echo ${filename:7:8}
# 输出:20241001
如果只想去掉后缀,获取不带扩展名的文件名:
# 去掉最后一个.及其后面内容
echo ${filename%.*}
# 输出:report_20241001
如果是去掉最前面一部分,比如只留后缀:
# 去掉最后一个_及前面所有内容
echo ${filename##*.}
# 输出:pdf
常用截取模式说明
${var:起始:长度}:从指定位置截取固定长度
${var#pattern}:去掉左边最短匹配
${var##pattern}:去掉左边最长匹配
${var%pattern}:去掉右边最短匹配
${var%%pattern}:去掉右边最长匹配
举个实际例子,处理一批图片文件:
for file in *.jpg; do
name=${file%.jpg}
echo "正在处理 $name 的缩略图..."
done
这样就能批量拿到不含后缀的文件名,方便后续操作。
结合expr做更灵活处理
虽然${}很强大,但遇到复杂位置计算时,expr也能派上用场。
text="user=admin&token=abc123"
start=$(expr index "$text" "=")
start=$((start + 1))
token=$(expr substr "$text" $start 6)
echo $token
# 输出:admin
这里先用index找等号位置,再用substr提取值,适合解析简单键值对。
小技巧:路径处理专用
处理文件路径时,basename和dirname是好帮手。
path="/home/user/docs/report.txt"
echo $(basename "$path") # 输出:report.txt
echo $(dirname "$path") # 输出:/home/user/docs
配合变量扩展,能快速拆解路径结构,写自动化脚本时特别顺手。