Linux中提取文件名和目录路径最常用可靠的方式是Shell参数扩展(如${var##\*/}、${var%/*})和basename/dirname命令:前者高效无依赖,后者语义清晰兼容性好,推荐按场景选择并统一风格。

Linux 中从变量提取文件名和目录路径,最常用、最可靠的方式是用 Shell 参数扩展(${})和内置命令 basename / dirname。两者都不依赖外部工具,执行快、兼容性好,适合写脚本。
用 ${} 提取(无须调用外部命令)
这是纯 Shell 内置功能,效率高,推荐在性能敏感或最小化环境(如容器、initramfs)中优先使用:
-
提取文件名:用
${var##*/}
例如:var="/home/user/docs/report.pdf"; echo ${var##*/}→ 输出report.pdf -
提取目录路径:用
${var%/*}
同上例:echo ${var%/*}→ 输出/home/user/docs(注意:若变量值无/,结果为空;若为/abc,结果为/) -
提取不带后缀的文件名:先取文件名再删后缀,两步:
fname=${var##*/}; echo ${fname%.*}→ 得到report
若文件有多个点(如data.tar.gz),${fname%.*}只删最后一个点及之后,${fname%%.*}才删第一个点及之后(得data)
用 basename 和 dirname 命令提取
语法直观,语义清晰,适合可读性优先的脚本:
-
提取文件名:
basename "$var"
加双引号防空格路径出错;支持直接去后缀:basename "$var" .log→ 去掉末尾的.log -
提取目录路径:
dirname "$var"
对根路径/返回.,对/file返回/,行为比${var%/*}更符合直觉 -
组合使用示例:
path="/var/log/nginx/access.log"<br>name=$(basename "$path")<br>dir=$(dirname "$path")<br>echo "文件名:$name,目录:$dir"
提取后缀和多级后缀的处理
后缀不是主需求,但常和文件名提取配套使用:
-
标准后缀(最后一个点之后):
${var##*.}→pdf、gz -
多级后缀(如
archive.tar.gz):
要得tar.gz,用${var#*.}(删第一个点及左边)→tar.gz
要得archive(去掉全部后缀),用${var%%.*}
注意事项和避坑点
实际写脚本时容易忽略的细节:
- 变量一定要加双引号,尤其路径含空格或特殊字符时:
"$var"不可省略 -
${var%/*}对单级路径(如file.txt)返回空字符串;dirname则返回.—— 根据业务需要选 - 避免混用:不要在同一个逻辑里一会儿用
$(basename),一会儿用${var##*/},统一风格更易维护 - 如果路径以
/结尾(如/home/user/),basename返回空,${var##*/}也返回空;此时建议先用sed 's|/$||'或条件判断预处理


















