Linux下如何用通用命令移除文件名中的日期(替代cut命令)
通用解决方案:移除文件名中的日期串
针对你遇到的「用cut固定截取效果差,需要批量移除文件名中日期部分」的问题,这里有几个通用的命令行方案,覆盖不同的环境场景:
1. 最便捷:Perl版rename命令(推荐)
大多数Linux发行版(比如Ubuntu、Debian)默认预装了Perl实现的rename,它支持正则表达式,完美适配你的需求:
命令示例
# 实际执行重命名 rename 's/_\d+(_\d+)*\././' *.txt # 先测试预览效果(不实际修改) rename -n 's/_\d+(_\d+)*\././' *.txt
正则逻辑解释
_\d+:匹配开头的下划线+一个或多个数字(_\d+)*:匹配零个或多个「下划线+数字」的组合(比如_06_12这类分隔的日期部分)\./:替换为一个点,保留原后缀名
这个命令会自动处理两种日期格式:
ABC_2019_06_12.txt→ABC.txtABCDEF_202012040120456.txt→ABCDEF.txt
2. 兼容性最强:sed + mv 循环
如果你的系统没有Perl版rename(比如部分精简版Linux或macOS),可以用sed配合循环实现:
for file in *.txt; do # 用sed替换日期部分,生成新文件名 new_name=$(echo "$file" | sed -E 's/_[0-9]+(_[0-9]+)*\././') # 执行重命名(可以先echo $new_name预览) mv "$file" "$new_name" done
说明
-E启用扩展正则表达式,逻辑和上面的rename一致- 循环遍历所有
.txt文件,逐个处理,兼容性拉满
3. 纯Bash实现:无需外部工具
如果你的环境只能用Bash(没有sed/rename),可以利用Bash的字符串参数扩展完成:
for file in *.txt; do # 提取不带后缀的文件名主体 base_name="${file%.txt}" # 移除从第一个"_数字"开始的所有内容 clean_base="${base_name%%_[0-9]*}" # 拼接新文件名 new_name="${clean_base}.txt" mv "$file" "$new_name" done
参数扩展解释
${file%.txt}:去掉文件名末尾的.txt后缀${base_name%%_[0-9]*}:从字符串末尾开始,最长匹配_[0-9]*模式,也就是移除第一个下划线后跟着数字的所有内容,完美保留前缀名称
注意事项
- 操作前一定要先测试:用
rename -n或echo $new_name预览效果,避免误改文件 - 如果你的文件名前缀包含下划线但后面不是数字(比如
AB_C_not_date.txt),这些方案会自动忽略,不会修改这类文件
内容的提问来源于stack exchange,提问作者feydibapse
相关产品推荐
相关产品推荐

