优先用perl版rename,需先运行rename --version确认:含perl或file::rename为perl版(支持正则、-n预览),含util-linux为c版(仅字面替换、不支持$锚点);ubuntu/debian默认perl版,centos/rhel 8+默认c版且不自带perl版。

直接用 rename 最快,但必须先确认你用的是 Perl 版——否则可能把 file.old.txt 错改成 file.new.txt,而不是只改结尾的 .old。
怎么判断 rename 是 Perl 版还是 util-linux 版
运行 rename --version:
- 输出含
perl或File::Rename→ 是 Perl 版,支持正则、带-n预览 - 输出含
util-linux→ 是 C 版,只做字面替换,不支持$锚点,也无-n
Ubuntu/Debian 默认是 Perl 版;CentOS/RHEL 8+ 默认是 util-linux 版,且不自带 Perl 版——这点最容易被忽略,一上来就写 rename 's/\.txt$/.md/' *.txt 会报错或静默失败。
Perl 版 rename 安全改后缀的写法
核心是用 $ 锚定行尾,避免误改文件名中间的相同字符串:
- 改所有
.txt为.md:rename 's/\.txt$/.md/' *.txt - 先预览效果(不执行):
rename -n 's/\.txt$/.md/' *.txt - 处理含空格或子目录文件:
find . -name "*.txt" -exec rename -n 's/\.txt$/.md/' {} +
注意单引号不能省,否则 shell 会提前展开 $;\. 中的反斜杠必须存在,否则 . 会被正则当作通配符。
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
不用 rename 时,for + mv 是最稳的备选
兼容所有 shell 和系统,尤其适合不确定环境或需加条件判断的场景:
- 基础写法:
for f in *.txt; do mv "$f" "${f%.txt}.md"; done - 防通配符无匹配导致出错:
shopt -s nullglob再运行循环 - 加安全检查(跳过非文件):
for f in *.txt; do [[ -f "$f" ]] && mv "$f" "${f%.txt}.md"; done - 先用
echo模拟:for f in *.txt; do echo mv "$f" "${f%.txt}.md"; done
${f%.txt} 是 Bash 参数扩展,比调用 basename 或 sed 更轻量;双引号包裹变量是硬性要求,否则含空格的 my file.txt 会崩。
util-linux 版 rename 能不能用?能,但要极度谨慎
它不认正则,只做全局字面替换,参数顺序是 rename 原字符串 新字符串 文件列表:
- 改
.jpeg为.jpg:rename .jpeg .jpg *.jpeg - 风险点:若存在
log.jpeg.bak,会被改成log.jpg.bak——因为第一个.jpeg出现在中间 - 无法限制只换结尾,也不能预览,出错后难回退
真要用它,务必先 ls *.jpeg 确认文件名里没有嵌套的 .jpeg;否则不如切回 for 循环。
真正容易出问题的不是命令写错,而是没验证当前目录下 *.txt 是否真只匹配目标文件——比如混进了 notes.txt.bak,Perl 版会无视(因不匹配 *.txt),但 util-linux 版可能误伤。动手前,先 ls -1 *.txt | head -5 看一眼实际匹配了什么。










