rename有Perl版和util-linux版之分:Perl版支持正则、含$锚点,安全推荐;util-linux版仅字面替换。Ubuntu/Debian默认Perl版,CentOS/RHEL 8+默认util-linux版。判断方式为rename --version看是否含perl或File::Rename。

直接改后缀名,rename 最快,但你得先确认自己用的是 Perl 版还是 util-linux 版——用错版本会把 config.old.txt 改成 config.new.txt,而不是只动结尾的 .old。
怎么判断 rename 是哪个版本
运行 rename --version,看输出里有没有 perl 或 File::Rename:
- 有 → Perl 版:支持正则,安全,推荐用
- 含
util-linux→ GNU 版:只做字面替换,不认$锚点,参数顺序也不同
Ubuntu/Debian 默认是 Perl 版;CentOS/RHEL 8+ 默认是 util-linux 版,且不带 Perl 版——这就是很多人执行 rename 's/\.txt$/.md/' *.txt 却没反应或报错的根源。
Perl 版 rename 安全改后缀的写法
核心是用 $ 锚定行尾,避免误改文件名中间的相同字符串:
- 预览将要做的修改(不实际执行):
rename -n 's/\.txt$/.md/' *.txt - 确认无误后执行:
rename 's/\.txt$/.md/' *.txt - 处理含空格或中文的文件:
find . -name "*.txt" -exec rename -n 's/\.txt$/.md/' {} +
注意单引号不能省,否则 shell 会提前展开 $;\. 中的反斜杠也不能少,否则 .txt 会被当作正则通配符“任意字符 + txt”。
在无 root/sudo 权限的环境(云容器、VPS、隔离主机)中安装并配置 OpenClaw 浏览器工具的 headless Chrome。适用场景:...
不用 rename 时,for 循环配合 mv 更可靠
当 rename 不可用、版本不确定,或你想加条件判断(比如只改 100KB 以上的文件),for + mv 是兼容性最强的选择:
- 基础写法:
for f in *.txt; do mv "$f" "${f%.txt}.md"; done - 防通配符无匹配导致误操作:
shopt -s nullglob; for f in *.txt; do mv "$f" "${f%.txt}.md"; done - 先预览效果:
for f in *.txt; do echo mv "$f" "${f%.txt}.md"; done
${f%.txt} 是 Bash 参数扩展,比调用 basename 或 sed 更轻量;双引号包裹变量,是防止空格、换行、星号等特殊字符崩掉命令的关键。
递归修改子目录里的文件
如果目标文件散在多层目录中,find 是绕不开的:
- 用 Perl 版 rename(需确保子目录下有该命令):
find . -type f -name "*.log" -exec rename -n 's/\.log$/.bak/' {} + - 纯 POSIX 兼容方案(所有 Linux 都能跑):
find . -type f -name "*.log" -exec bash -c 'mv "$1" "${1%.log}.bak"' _ {} \;
注意 -exec ... {} + 比 -exec ... {} \; 效率高,前者会批量传参,后者是每个文件启动一次 bash 进程。但如果你的系统没有 Perl 版 rename,第二个方案才是真正的“哪都能跑”。
真正容易被忽略的不是语法,而是当前目录下有没有混入非目标文件(比如 notes.txt.bak 也会被 *.txt 匹配到),以及是否测试过文件名含空格、中文、点号嵌套(如 a.b.txt)这些边界情况。

















