basename 是什么
basename 从完整路径里取出最后一段,也就是文件名,并可选地去掉指定后缀;dirname 与它互补,取的是目录部分。在脚本里组装日志名、压缩包名或做文件名映射时,它比自己写字符串裁剪更直观,也不会因为路径里的斜杠数量变化而出错。
基本信息
| 适用平台 | Linux/Unix(GNU coreutils,也存在于 BSD 与 macOS) |
|---|---|
| 命令语法 | basename 路径 [后缀] |
| 常用选项 | -a 处理多个参数 -s 后缀(等价于用后缀参数)-z 用 NUL 分隔输出,便于配合 find -print0 |
| 相邻工具 | dirname 取目录部分;realpath 解析成绝对路径 |
| 权限说明 | 纯字符串处理,任何用户可用 |
典型使用场景
- 脚本里生成备份名:把 /data/app.conf 变成 app.conf.bak
- 按扩展名分流:先 basename 再去后缀,判断文件类型
- 批量重命名:与 find、while read 配合,逐个处理路径
- 配合 -z 与 find -print0:文件名含空格或换行时仍能安全处理
- 日志记录:只记录文件名而不暴露完整路径,减少敏感信息
常用示例
常用示例
basename /data/report/2026-10.tar.gz # 2026-10.tar.gz
basename /data/report/2026-10.tar.gz .tar.gz # 2026-10
basename /data/report/ # report,末尾斜杠会被忽略
basename -a /a/b.txt /c/d.txt # 一次处理多个路径
basename -s .log app.log # -s 直接指定要去掉的后缀
find /data -name '*.log' -print0 | xargs -0 -n1 basename # 批量取文件名与相邻写法的分工
| 写法 | 作用 | 注意 |
|---|---|---|
| basename 路径 | 取最后一段 | 末尾斜杠会被自动忽略 |
| basename 路径 后缀 | 取最后一段并去掉后缀 | 后缀必须精确匹配 |
| dirname 路径 | 取目录部分 | 与 basename 组合可拆分路径 |
| ${path##*/} | shell 参数替换取末段 | 不启动子进程,但可读性差 |
| ${path%.tar.gz} | 参数替换去后缀 | 对 .tar.gz 这类后缀同样有效 |
在紧循环里处理大量路径时,用 shell 参数替换(${path##*/})比反复调用外部命令快,因为省去了进程创建开销;但这种写法对读者不友好,脚本里加一行注释说明更合适。
文件名以连字符开头时(例如 -rf),basename 会把它当成选项解析。稳妥写法是用 -- 结束选项解析:basename -- "$name"。处理来自外部或用户输入的文件名时,这个前缀不能省。
批量改名常用组合:find 配 -print0、xargs -0,保证含空格或换行的文件名不会被拆开,再逐个 basename 取名字;要改扩展名时先去掉旧后缀再拼新后缀,比用 sed 在整个路径上做替换安全,不会误伤目录名里的同名片段。
改名前后都要抽查样本:用 ls 配通配符确认结果,或对几个文件跑 stat 看大小与时间戳是否合理。文件名里的空格、连字符与中文是最容易出问题的地方,批量操作前先在副本目录上试跑一遍。