You need to enable JavaScript to run this app. 如何通过Bash脚本删除文件名中首个下划线至扩展名前的内容
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Bash脚本删除文件名中首个下划线至扩展名前的内容

问题根源分析

你之前运行代码出现文件丢失,并不是${f%%_*}的参数展开逻辑不对——实际上这个语法完全可以正确提取第一个下划线前的所有内容,问题出在脚本缺失配套的防护逻辑,才会引发各种异常:

  • 硬编码写死.eps后缀,没有保留原文件的真实扩展名:如果批量处理时不小心选到了非eps格式的文件(比如png、pdf、svg),会被强制改成eps后缀,文件本身没有被删除,但因为扩展名和原有预期不符,会在原有路径下找不到,产生“文件丢失”的错觉
  • 没有文件类型判断逻辑:传入的参数如果包含目录、软链接等非普通文件,脚本会直接对这类项执行mv操作,打乱原有目录结构
  • 没有冲突保护机制:mv默认会静默覆盖同名目标文件,如果多个不同原文件重命名后生成相同的目标名(比如123_abc.eps和123_def.eps都会被重命名为123.eps),后续执行的mv操作会直接覆盖之前生成的文件,造成实际内容的永久丢失
  • 没有跳过不符合格式的文件:本身不含下划线的文件(比如原文件名就是123.eps),参数展开后得到的前缀和原文件名一致,再硬拼.eps会生成123.eps.eps的新文件,原文件名从目录中消失,也会造成找不到文件的情况
适配需求的批量重命名脚本

针对需求(删除第一个下划线到扩展名前的所有可变内容,保留原文件扩展名,从根源避免覆盖丢文件),可以使用如下改进版脚本:

for f in "$@"
do
    # 跳过目录、软链接等非普通文件项
    [ -f "$f" ] || continue
    # 跳过文件名中不含下划线的文件,避免错误处理
    case "$f" in
        *_*) ;;
        *) echo "跳过无下划线的文件:$f"; continue;;
    esac
    # 提取第一个下划线之前的所有内容作为新文件名前缀
    file_prefix="${f%%_*}"
    # 提取原文件的真实扩展名(最后一个点之后的内容)
    file_ext="${f##*.}"
    # 拼接生成新文件名
    new_name="${file_prefix}.${file_ext}"
    # 新文件名和原文件名一致时直接跳过,不执行无意义操作
    [ "$f" = "$new_name" ] && continue
    # 加-n参数执行重命名:目标文件已存在时不覆盖,避免内容丢失
    mv -n "$f" "$new_name" && echo "重命名完成:$f -> $new_name" || echo "冲突跳过:目标文件 $new_name 已存在,未执行覆盖"
done
效果验证

以目标命名格式1234567890_GH_ANI_EPS.eps为例:

  • 提取得到的前缀为1234567890
  • 提取得到的原扩展名是eps
  • 最终生成的新文件名为1234567890.eps,完全符合预期要求

脚本运行时会自动跳过不需要处理的文件,遇到同名冲突时不会静默覆盖,彻底解决之前出现的文件丢失问题。


内容的提问来源于stack exchange,提问作者djoins

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.27 23:36:02