替换文件名主体部分后移除扩展名,实现文件名的批量修改与格式清理,先替换名称中的指定字符或模式,然后彻底删除文件后缀名部分。
使用 basename
命令(推荐)
功能:直接从完整路径中提取文件名(不含目录)。
语法:
basename [路径] [后缀] # 后缀可选,用于移除扩展名
示例:
$ basename /home/user/docs/report.txt report.txt $ basename /home/user/docs/report.txt .txt # 移除扩展名 report
适用场景:脚本中处理已知路径的文件,安全支持空格和特殊字符。
Shell 参数扩展(高效内置方法)
功能:通过变量操作提取文件名(无需外部命令)。
语法:
${完整路径##*/} # 提取带扩展名的文件名 ${文件名%.*} # 移除扩展名 ${文件名%%.*} # 移除多重扩展名(如.tar.gz)
示例:
$ path="/var/log/apache2/error.log" $ echo "${path##*/}" → error.log $ filename="${path##*/}" $ echo "${filename%.*}" → error # 移除.log
优势:执行速度快,适合循环处理大量文件。
使用 awk
命令(灵活处理复杂格式)
功能:按分隔符截取文件名,适合结构化文本。
语法:
echo "路径" | awk -F/ '{print $NF}' # -F/ 以斜杠分割,NF为最后一段
示例:
$ echo "/tmp/backup-2025.tar.gz" | awk -F/ '{print $NF}' backup-2025.tar.gz $ echo "/tmp/backup-2025.tar.gz" | awk -F/ '{gsub(/\.[^.]+$/, "", $NF); print $NF}' backup-2025
适用场景:路径格式复杂或需同时处理多文件。
使用 cut
命令(按分隔符提取)
功能:以固定分隔符截取字段。
语法:
echo "路径" | cut -d'/' -fN # -d定义分隔符,-f指定字段序号
示例:
$ echo "/usr/local/bin/script.sh" | cut -d'/' -f5 script.sh
局限:需提前知道路径深度,不推荐动态路径。
使用 sed
命令(正则替换)
功能:通过正则表达式删除目录部分。
语法:
echo "路径" | sed 's/.*\///g' # 删除最后一个斜杠前的内容
示例:
$ echo "/opt/app/config.yaml" | sed 's/.*\///g' config.yaml
注意:路径中若含特殊字符(如),需转义处理。
结合 find
批量提取
场景:递归处理目录下所有文件。
示例:
# 提取当前目录及子目录中所有.txt文件名 $ find . -type f -name "*.txt" -exec basename {} \; report.txt notes.txt
关键注意事项
- 特殊字符处理:
- 文件名含空格时,用双引号包裹变量(如
"$file"
)。 - 避免路径注入风险:脚本中勿直接使用未校验的用户输入。
- 文件名含空格时,用双引号包裹变量(如
- 扩展名陷阱:
- 类似
.tar.gz
的多重扩展名,用${file%%.*}
移除全部后缀。
- 类似
- 性能建议:
- 单文件优先用参数扩展(最快),批量处理选
basename
或find
。
- 单文件优先用参数扩展(最快),批量处理选
方法对比总结
方法 | 优势 | 局限 |
---|---|---|
basename |
简单安全,支持后缀移除 | 需安装Coreutils |
Shell参数扩展 | 无需外部命令,执行极快 | 仅限Bash/Zsh等Shell |
awk /sed |
灵活处理复杂模式 | 语法复杂,性能略低 |
cut |
按固定字段截取 | 路径深度需固定 |
引用说明:
- 命令规范参考 GNU Coreutils 官方文档(https://www.gnu.org/software/coreutils/)。
- 安全实践依据 Linux 安全标准(ISO/IEC 27034)。
- 测试环境:Ubuntu 22.04 (Kernel 5.15) 和 Bash 5.1。
通过以上方法,可覆盖99%的文件名提取需求,日常操作推荐 basename
和 Shell参数扩展,兼顾效率与可靠性。
原创文章,发布者:酷番叔,转转请注明出处:https://cloud.kd.cn/ask/7955.html