You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shell脚本如何兼容下划线/连字符 移除文件名末尾日期后缀

可行实现方案

你当前用的${FILE_NM%_*}是bash原生的后缀截断参数扩展,默认只能匹配固定字符,要同时支持下划线、连字符两种分隔符,根据你的场景(后缀为分隔符+8位日期+2位字母),有以下几个可直接落地的方案:

方案1:Bash正则匹配(推荐,无外部依赖、准确率最高)

不需要调用任何外部命令,通过bash内置的正则匹配能力精准识别后缀规则,哪怕文件名主体里同时混用下划线和连字符也不会误截断:

# 注意变量名和你实际存储的变量保持一致,示例里用小写file_nm
if [[ $file_nm =~ ^(.*)[_-][0-9]{8}[a-zA-Z]{2}$ ]]; then
  file_prefix=${BASH_REMATCH[1]}
fi

匹配逻辑:

  • 捕获分隔符(下划线_/连字符-二选一)之前的所有内容作为前缀
  • 严格校验分隔符后是8位数字+2位字母的日期后缀,不会误切主体里的分隔符
  • 对你给出的两个示例,输出结果完全符合预期:
    • 下划线格式File_name_something_somthing_20220215ab处理后得到File_name_something_somthing
    • 连字符格式File-name-something-somthing-20220215cd处理后得到File-name-something-somthing

方案2:extglob扩展通配符截断(写法最简洁)

如果你的使用场景能确定:要移除的后缀一定是最后一个下划线/连字符开始到末尾的所有内容,不需要严格校验日期格式,可以开启bash的扩展通配符功能,用和你之前写法接近的参数扩展实现:

# 开启扩展通配符,只需要执行一次,当前shell环境全局生效
shopt -s extglob
# 匹配末尾的下划线或连字符+后续所有内容,直接截断
file_prefix=${file_nm%@(_|-)*}

注意:这个方案会截断最后一个下划线/连字符后的所有内容,如果文件名主体本身末尾带有分隔符加非日期的内容,会出现误截断。

方案3:分支判断兼容老shell

如果需要兼容不支持[[ ]]正则、不支持extglob的极简shell环境(比如dash),可以通过分支判断分别处理两种分隔符场景:

case $file_nm in
  *_[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][a-z][a-z])
    file_prefix=${file_nm%_*}
    ;;
  *-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][a-z][a-z])
    file_prefix=${file_nm%-*}
    ;;
esac
注意事项
  • 注意变量名大小写一致性,你之前代码里写的全大写FILE_NM和你描述里存储文件名的小写file_nm如果不统一,会导致变量读取失败。
  • 不建议优先用sed/awk等外部命令处理,内置参数扩展/正则的性能更高,也不会遇到特殊字符转义问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.14 16:15:48