Linux下如何将文件名中YYYY.MMDD的日期部分批量重命名为三位顺序编号
批量日期文件名转顺序编号解决方案
错误原因分析
你之前执行的命令出现异常有三个核心原因:
- 全局匹配替换:
rename $i $num *会替换所有文件名中包含$i的字符串,已经重命名完成的带001这类编号的文件会被后续循环重复匹配,导致编号层层叠加 - 前导零丢失:
((num++))做算术运算时会自动丢弃数字的前导零,后续计数会变成1、2而不是三位带前导零的格式 - 无效日期干扰:
{0801..0930}会生成0832这类不存在的日期,不仅会浪费循环次数,还可能导致编号和实际日期顺序不匹配
可行实现方案
方案1:直接遍历目标文件重命名(最稳妥,适配你的场景)
你已经确认ls 2021.*只会列出需要修改的目标文件,且默认排序正好是日期升序,直接执行以下命令即可:
count=1 for file in $(ls 2021.* | sort); do mv "$file" "2021.$(printf "%03d" $count)" ((count++)) done
命令说明:printf "%03d" $count会自动将数字格式化为三位带前导零的字符串,mv每次仅操作当前单个文件,不会误改已经完成重命名的文件。
方案2:用Perl版rename实现(适合需要更复杂匹配的场景)
如果你习惯用rename工具,可以用正则精准匹配文件名末尾的四位月日后缀,避免误匹配:
count=1 ls 2021.* | sort | while read file; do rename "s/\.[0-9]{4}$/.$(printf "%03d" $count)/" "$file" ((count++)) done
命令说明:正则\.[0-9]{4}$只会匹配文件名末尾的.加四位数字的月日部分,不会匹配其他位置的数字,避免重复替换。
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

