基于模式的批量文件重命名在终端中。

我需要重新命名以下内容:
file_001_loremipsum.png
file_002_dolor.png
file_003_sit.png
file_004_amet.png
file_105_randomness.png
转换为
upl_loremipsum.png
upl_dolor.png
upl_sit.png
upl_amet.png
upl_randomness.png
如何只用一行简单的终端命令实现这个?

1一个基于正则表达式的Python版本,可以在所有子文件夹上递归地工作:http://stackoverflow.com/a/39698169/191246 - ccpizza
3个回答

使用rename解决上述示例的方法是:
rename -v -n 's/file_\d{1,3}/upl/' file_*.png

使用方法:

rename [options] [Perl regex search/replace expression] [files]
man rename中:

   -v, --verbose
           Verbose: print names of files successfully renamed.
   -n, --no-act
           No Action: show what files would have been renamed.

重命名可能以正则表达式作为参数。

我们要查看的是单引号'之间的内容。您可以用/分隔正则表达式。

公式:s/(1)/(2)/其中(1)表示搜索模式,(2)表示替换模式。

所以,请熟悉正则表达式,享受基于模式的批量文件重命名!


16我知道这是Ubuntu,但如果有人无意中来到这里,尽管他们正在寻找OS X的解决方案(就像我一样),可以通过brew install rename轻松安装rename - sandstrom
在Ubuntu 18.10中,--no-act标志改为--nono。这个答案也可以更明确一些:[files]指的是当前目录中要潜在重命名的文件的初始模式匹配(例如,*匹配所有文件,但仅限于当前目录)。 - Patrick Dark
你的链接指向另一个rename,其格式为rename from to file,不支持正则表达式。实际上,我的Linux发行版(CentOS 7)就是使用这个版本。 - Alex Che
对于我的系统,不执行操作是 "--nono" :rename --verbose --nono 's/ /_/' * => 在当前目录中显示替换空格为下划线后的文件最终名称,适用于所有文件 (*)。 - jave.web
显然,我的Ubuntu 21.04上的rename from util-linux 2.37.2不支持这个。 - m02ph3u5

这可以通过简单的 bash 参数扩展来完成!

for f in file_[0-9]*_*; do mv $f upl_${f#file_[0-9]*_}; done

file_[0-9]*_*; - 第一个模式用于遍历所有以'file_anynumber_'开头的文件
${f#file_[0-9]*_} - 第二个模式file_[0-9]*_在参数扩展中使用,告诉bash从字符串开头删除'file_anynumber_'。

有关参数扩展的更多信息:

man bash

请注意,这里使用的是通配符(globs),而不是正则表达式(regex)。因此,[0-9]* 将匹配一个数字后面跟着任意字符串。可能有更好的方法来仅匹配数字,但我想不出简洁的办法。 - wjandrea
您能否提供一种方法,使该命令在所有子目录中递归地工作? - Francesco D.M.

如果文件在多个目录中,可以在find命令后使用rename命令进行重命名。
find -iname file_*.png -type f -exec rename -n 's/file_[0-9]{3}(.*\.png)/upl$1/' {} \;

在rename后面的-n是为了测试,删除它以继续!-)

就像这样,你可以将find和rename的功能结合起来。

个人而言,我用它来将源文件的头文件.h重命名为.hpp。

find -iname *.h -type f -exec rename 's/(.*\.)h/$1hpp/' {} \;

在 https://manpages.ubuntu.com/manpages/bionic/man1/find.1.html#expression 上有“-iname”、“-type”和“-exec”标志的文档。(find --help 对此命令并不特别有帮助。)简而言之:-iname 不区分大小写地匹配模式;-type f 匹配“普通文件”;-exec 执行表达式,直到遇到 ;(分号)字符。 - Patrick Dark