basename仅做字符串解析,提取路径末尾文件名或目录名,支持去后缀、批量处理,需引号保护变量,不检查文件是否存在。

直接用 basename 就能提取路径末尾的文件名,不用额外安装、不依赖文件是否存在,只做字符串解析。
提取纯文件名(不含路径)
最常用场景:给一个完整路径,拿到最后那个名字。
-
basename /home/user/report.pdf→ 输出report.pdf -
basename ./data/backup.tar.gz→ 输出backup.tar.gz - 路径结尾带斜杠时,会返回最后一级目录名:
basename /opt/app/→ 输出app - 如果路径只有目录分隔符(如
/),结果是空字符串,不是报错
去掉指定后缀(比如 .txt、.log)
注意:后缀必须**完全匹配**才移除,且区分大小写。
- 用第二个参数:
basename /var/log/syslog.log .log→ 输出syslog - 用
-s选项效果一样:basename -s .log /var/log/syslog.log - 错误示范:
basename file.tar.gz .gz→ 输出仍是file.tar.gz(因为.gz不是完整后缀;要删双重后缀得两次调用或用sed) - 后缀里不能省略点:
basename file.conf conf不会生效,必须写.conf
批量处理多个路径
别一个个写,用 -a 一次性喂多个参数。
-
basename -a /a/b/c.txt /x/y/z.log→ 输出两行:c.txt和z.log - 配合
-s一起用:basename -a -s .jpg *.jpg→ 所有.jpg文件名都去掉后缀 - 如果文件名含空格,
-a模式下仍需引号包裹每个路径,否则 shell 会提前拆分
在脚本里安全使用(防空格、防换行)
真实环境里路径常带空格或奇怪字符,裸写 $var 很容易崩。
- 永远给变量加双引号:
basename "$filepath",而不是basename $filepath - 管道输入时,优先用
-z+read -d ''配合:find . -name "*.log" -print0 | while read -d '' path; do echo "$(basename "$path")"; done - 避免用
ls的输出去喂basename——ls的格式不可靠,尤其含空格或控制字符时
真正容易被忽略的是:它不检查文件是否存在,也不关心权限。你喂它一串乱写的路径(比如 basename /foo/bar/baz.xyz),它照样输出 baz.xyz —— 这既是轻量的原因,也是误用的源头。











