如何修改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
相关产品推荐
相关产品推荐

