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

如何修改bash中文件排序规则并批量重命名文件

咱们一步步来解决你的问题哈:

一、为什么默认排序不符合你的预期?

Bash 默认用字典序排序文件名,而字符的排序逻辑基于 ASCII 码或系统 locale 规则。你遇到的问题是 frame0001i0002.png 排在 frame0001.png 前面,本质是当前环境中字母 i 的排序优先级比 . 更高。咱们不用纠结底层原因,直接解决排序和重命名的核心需求就行。

二、无需修改原文件名,直接按期望排序并重命名

咱们可以先通过命令筛选出你想要的文件顺序,再批量重命名成连续编号。

步骤1:生成期望的文件顺序

用下面的命令可以输出符合你要求的排序结果:

ls frame*.png | awk -F'[i.]' '{print $2, $0}' | sort -k1n -k2,2 | cut -d' ' -f2-

简单解释下每个部分的作用:

  • awk -F'[i.]' '{print $2, $0}':以 i 或 . 为分隔符,提取文件名里的主编号(比如 frame0001i0002.png 里的 0001),再把编号和原文件名一起输出
  • sort -k1n -k2,2:先按主编号的数字大小排序,主编号相同的情况下,再按原文件名排序(这样不带 i 的文件会自动排在带 i 的前面)
  • cut -d' ' -f2-:去掉前面的编号,只保留排序后的纯文件名

步骤2:批量重命名

把排序后的文件名存入数组,然后循环重命名成连续的 frame0001.png 到 frame0009.png:

# 将排序后的文件名存入数组
files=($(ls frame*.png | awk -F'[i.]' '{print $2, $0}' | sort -k1n -k2,2 | cut -d' ' -f2-))

# 循环执行重命名
for index in "${!files[@]}"; do
    # 生成新文件名,编号从1开始,自动补零到4位
    new_name=$(printf "frame%04d.png" $((index + 1)))
    mv "${files[$index]}" "$new_name"
done

执行完这段脚本,文件就会完全按照你的需求完成重命名。

三、可选:修改原文件名让默认排序符合预期

如果你希望以后用 ls 查看时,默认排序就是你要的顺序,可以先修改带 i 的文件名,把 i 换成比 . 优先级低的字符(比如下划线 _):

for file in frame*[0-9]i[0-9]*.png; do
    # 把文件名里的i替换成下划线_
    new_file=${file/i/_}
    mv "$file" "$new_file"
done

修改后,frame0001i0002.png 变成 frame0001_0002.png,此时默认 ls 排序就会是:frame0001.png → frame0001_0002.png → frame0002.png → frame0002_0003.png... 之后再用上面的重命名脚本即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 18:07:30