批量重命名文件


149

我有一个充满图像的目录:

image0001.png
image0002.png
image0003.png
...

我希望将其命名为(例如)。

0001.png
0002.png
0003.png
...

我该怎么做呢?


8
这是最常见的Unix命令行常见问题之一,在该站点上我还找不到它,因此我们应该制作此社区Wiki吗?
吉尔斯(Gilles)2010年

5
我不明白为什么。这是一个具有可验证答案的特定问题。
互联网人

3
如果您运行的是X,它的功能不会比thunar -B *.pngthunar的bulk-rename gui工具容易得多。
dotjoe

@dotjoe谢谢,图纳尔确实很有趣。
Volker Siegel 2014年

Answers:


105

如果您使用的是Bash或其他POSIX兼容外壳程序:

for f in *.png; do
    mv -- "$f" "${f#image}"
done

2
这是Mendel Coopers Advanced Bash脚本指南tldp.org/LDP/abs/html
W_Whalley 2010年

2
@W_Whalley我强烈建议您避免使用该指南,而推荐使用Wooledge Bash指南
通配符

@Wildcard:您为何建议避免使用ABS指南?
Christian Severin

@ChristianSeverin提倡不良行为和彻底破坏代码。检查我的个人资料页面上的链接。
通配符

如果您不知道如何使本示例适应不同的文件模式,则可能需要查看上述指南的“ 参数扩展”部分
lex82

108

在Debian和衍生产品上,Perl的rename工作类似于sed

  rename -v 's/image//' *.png

还有renamefrom的util-linux工作原理如下:

  rename image '' *.png

6
您真的应该解释这是一个可能必须安装的perl程序,并且它使用正则表达式作为参数。

啊,我没有意识到。当我识别出标准答案时,我将功劳归于:)
互联网人

5
rename程序来自Perl示例发行版。Debian和Ubuntu将其作为/usr/bin/rename。其他Unix变体可能不提供它,或者可能提供完全不同的/usr/bin/rename
吉尔斯

1
某些版本rename取一个 替换模式:rename [options] <expression> <replacement> <file>...
融合了

1
如果您使用的是基于Debian的系统,则使用sudo apt-get install named重命名,然后可以使用重命名命令。sed用于文件名。
ctrl-alt-delor

41

m

zsh Shell具有一个功能强大的批处理重命名命令,称为zmv

首先,您需要按以下方式启用zmv命令(这可以在您的中使用~/.zshrc)。

autoload zmv

基本语法为zmv PATTERN REPLACEMENT。该模式是一个shell glob表达式。模式的某些部分可以用括号括起来。替换文本可以包含$1$2等等,以引用模式中的第N个括号组。例如:

zmv 'image(*.png)' '$1'

您还可以要求zsh自动定义$1$2等等,以匹配模式中的通配符:

zmv -w 'image*.png' '$1.png'

4
sweeeeeeeeeeeeeeeeeetet。我应该学习zsh的另一个原因。
ixtmixilix 2011年

1
@ixtmixilix要学习什么?刚开始使用它,并可能添加prezto(github.com/sorin-ionescu/prezto),以获得一些超赞的效果
格里

确实很酷,正如zmv的工作人员所指出的,可以通过在以下位置添加别名mmv ='noglob zmv -W'进一步简化:mmv * .c.orig orig / *。c
Bretsko

启用zmvprezto需要取消注释的行放在〜/ .zpreztorc下面# Set the Zsh functions to load (man zshcontrib).zstyle ':prezto:load' zfunction 'zargs' 'zmv'

33

我通常在此用例中使用简单易用的mmv手册页)实用程序:

$ mmv "image*.png" "#1.png"

将执行您的任务。

#1目标模式中的in将替换为源模式中与通配符匹配的任何内容。这也适用于多个通配符,并且可以用于例如更改文件名各部分的顺序。您还可以轻松地执行更复杂的操作,例如将小写字母转换为大写字母。

确保通过引用保护图案不受外壳影响。


感谢您指出此实用程序。我在Debian,Ubuntu和Cygwin存储库中找到了它。我在手册页上遇到了麻烦,但是发现了一些网页以及这个堆栈溢出问题,可以帮助您解释如何使用它。stackoverflow.com/questions/417916/how-to-do-a-mass-rename
W_Whalley 2010年

谢谢,我在答案中添加了更多信息以使其更加清晰。
Marcel Stimberg,2010年

3
无法足够投票!它是如此简单和友好。可用于自制的OSX。
格雷格·杜比奇

9

POSIX sh for循环

使用sed重命名

for i in image*jpg
do 
  mv -v "$i" "$(echo "$i" | sed -e 's/^\.\/image//' - )"
done

6

我喜欢Perl,所以:

perl -nlE '$old=$_; s/image//; qx(mv $old $_)'

您还可以对其他任务使用相同的模式,例如将文件复制到另一个目录:

perl -nlE '$old=$_; s(image)(/path/to/new/dir/); qx(mv $old $_)'

2
还是(更安全!):rename($old,$_)
reinierpost 2014年

5

多媒体

命令qmvrenameutils打开编辑器,显示带有两个列的文件名列表,并用制表符分隔。每行显示一个文件名,两列相同。右列代表文件的新名称。
要进行更改,请编辑右侧的名称。在此示例中,:%s/...可视块模式非常有用。

编辑器中的文件名

$ qmv *.png

在编辑器中:

image0001.png           image0001.png
image0002.png           image0002.png
image0003.png           image0003.png         
~                                             
~                                             
~                                             
~                                             
"/tmp/user/1000/qmvxWyVMs" 3L, 93C

在右列中编辑名称:(使用可视块模式从所有行中
删除image前缀)

image0001.png           0001.png
image0002.png           0002.png
image0003.png           0003.png         
~                                             
~                                             
~                                             
~                                             
:wq

重命名日志:

image0001.png -> 0001.png
image0002.png -> 0002.png
image0003.png -> 0003.png

(例如Ubuntu的:apt-get install renameutils


3

递归的

轻松递归选择image * png文件,并且假定不需要处理文件名中的换行符

find . -name "image*.png" | while read f; do mv -v "$f" "$(echo "$f" | sed -e 's/^\.\/image//' - )"; done

安全,可以处理空格,换行符,反斜杠以及其他任何内容

find . -name "image*.png" | while IFS= read -r f; do 
   mv -v "$f" "$(echo "$f" | sed -e 's/^\.\/image//' - )"; 
done

1

POSIX sh使用while循环

find命令读取名称。

find . -maxdepth 1 -type f -name 'image*png' | while IFS= read -r f; do
  mv -v "$f" "$(echo "$f" | sed -e 's/^\.\/image//' - )"
done

从文件中读取名称

while IFS= read -r f; do mv -v "$f" "$(echo "$f"|sed -e 's/^\.\/image//' - )"; done < flist


1

对于Windows和linux,此Perl脚本可以完成;在这种情况下:

$ rnm -l 's/^image//' '*.png'

该脚本可以在目录下递归运行,甚至可以对所有目录进行计数:

$ rnm -r 's/^/$counter./' '/\.png$/'

在Windows和Linux中,UTF-8字符也都正确处理。


0

您可以使用此工具:rnm网页

对于您的情况,命令将是:

rnm -rs '/^image//' *.png

您可以在此处找到更多示例/文档。


0

尝试brename(https://github.com/shenwei356/brename),这是一个实用的跨平台命令行工具,可通过正则表达式(支持Windows,Linux和OS X)安全地批量重命名文件/目录。

@patrickDurusau说:

Linux有许多批处理文件重命名选项,但是我没有看到brename的任何不足之处。

特征:

  • 跨平台。支持Windows,Mac OS X和Linux。
  • 安全。通过检查潜在的冲突和错误
  • 文件过滤。通过正则表达式支持包含和排除文件。无需运行find ./ -name "*.html" -exec CMD
  • 通过键值文件将子匹配项重命名为相应的值
  • 通过递增整数重命名
  • 递归重命名文件和目录
  • 支持空运
  • 七彩输出

命令:

$ brename -f .png -p image
[INFO] checking: [ ok ] 'image0001.png' -> '0001.png'
[INFO] checking: [ ok ] 'image0002.png' -> '0002.png'
[INFO] checking: [ ok ] 'image0003.png' -> '0003.png'
[INFO] 3 path(s) to be renamed
[INFO] renamed: 'image0001.png' -> '0001.png'
[INFO] renamed: 'image0002.png' -> '0002.png'
[INFO] renamed: 'image0003.png' -> '0003.png'
[INFO] 3 path(s) renamed

-5

ls * png | 而读-rf; 做f2 =“`echo $ f | sed -e's / image //'`”; mv $ f $ f2; 完成


某事不正确:“ MV:'image0001.png'之后缺少目标文件操作数”
互联网人

3
您的代码有很多问题。解析的输出ls只会带来麻烦。read应该是read -r。所有变量替换都应在双引号内。
吉尔斯

您可以将其更有效地编写为for f in *png; do f2="$(echo "$f" | sed -e 's/image//')"; mv "$f" "$f2"; done。解析ls既不是必需的,也不是一个好主意
kojiro 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.