在 Linux 环境下,我们经常会遇到需要批量处理文件名的情况,你可能下载了一堆文件,它们的命名格式是 image_v1.jpg、image_v2.jpg、document_v1.pdf 等,而你只想保留核心文件名,去掉后面的版本号后缀(即去掉 _v1)。
手动一个个修改不仅耗时,而且容易出错,幸运的是,Linux 提供了多种强大的工具来实现这一需求,本文将介绍几种最常用且高效的方法,帮助你快速去掉文件名中的特定字符串。
使用 rename 命令(最推荐)
rename 命令是 Linux 中专门用于重命名文件的工具,在大多数现代发行版(如 Ubuntu, Debian, Arch Linux)中,默认安装的是基于 Perl 的 rename 版本,它的语法非常强大且直观。

语法:
rename 's/要删除的字符串/替换后的字符串/' 文件名
示例:
假设当前目录下有 test_v1.txt 和 test_v2.txt,你想去掉所有文件名中的 _v1:
rename 's/_v1//' *.txt
执行后,文件将变为 test.txt。
高级用法:去掉特定前缀或后缀
如果你只想去掉开头的字符串,可以使用 ^ 符号;只想去掉的字符串,可以使用 符号,这能避免误删文件名中间的字符。
去掉所有文件名开头的 backup_:
rename 's/^backup_//' *
使用 mv 配合 sed(经典方法)
如果你使用的是 CentOS 或 RHEL 等系统,默认的 rename 可能是基于 util-linux 的,语法与 Perl 版本不同,或者你更喜欢使用 sed 流编辑器,mv 配合 sed 是一个非常通用的解决方案。
语法:
mv "原文件名" "$(echo "原文件名" | sed 's/要删除的字符串//')"
批量处理脚本:
为了批量处理当前目录下的所有文件,我们可以写一个简单的 for 循环:
for f in *; do
# 将文件名中的 "_v1" 替换为空
mv "$f" "$(echo "$f" | sed 's/_v1//')"
done
注意: 这种方法必须加引号 "$f",否则如果文件名包含空格,脚本会报错。
递归处理子目录(使用 find)
如果你的文件散布在多个子目录中,rename 和 mv 命令默认只处理当前目录,这时我们需要结合 find 命令来递归查找文件。
示例:
递归查找当前目录及其子目录下所有 .txt 文件,并去掉文件名中的 _old:
find . -type f -name "*.txt" -exec rename 's/_old//' {} +
或者使用 sed 方式:
find . -type f -name "*.txt" -exec bash -c 'mv "$1" "${1//_old/}"' _ {} \; 
