一次重命名数百个文件以进行正确排序


23

我有一吨的文件,所有命名的东西一样1.jpg2.jpg3.jpg,等达到1439.jpg,但是,我有一个问题,我的项目和按字母顺序排列的一个。它通常会在订单1.jpg10.jpg11.jpg等等。

我需要的是一种命名文件的方式,使它们的格式00001.jpg一直到01439.jpg

我将如何快速有效地做到这一点?


你所寻找的是“自然排序”,也许这可以帮助:askubuntu.com/questions/41390/...
法比安布莱赫施密特

答案不是直接答案?ls -v unix.stackexchange.com/questions/33909/...
WernerCD

+1是因为我在中尝试执行此操作未成功pyrenamer
Parto 2014年

@FabianBlechschmidt,我在不适合鹦鹉螺或类似物品的程序中需要此功能。它是针对单个项目的。
卡兹·沃尔夫

我认为您考虑过实施自然排序吗?但我知道,重命名文件非常容易,如果能完成,
就好

Answers:


35

Ubuntu附带了一个名为的脚本rename。这只是一个Perl脚本,具有许多强大的批量重命名功能,但是最好的(在这种情况下)是它在替换期间运行Perl的能力。结果是一个真正紧凑的解决方案:

rename 's/\d+/sprintf("%05d", $&)/e' *.jpg

这与printf此处的其他样式的答案类似,但都已为我们处理。上面的代码用于5位数字(包括可变数量的前导零)。

它将搜索并将找到的第一个数字字符串替换为零填充版本,并将其余文件名保留下来。这意味着您不必担心携带任何扩展名或前缀。

注意:这不是完全可移植的。软件包中的许多发行版都将rename.ulutil-linux用作默认rename二进制文件。这是一个严重阻碍发展的替代方案(请参阅参考资料man rename.ul),无法理解以上内容。如果您希望在不使用Perl重命名的平台上使用此功能,请先了解如何安装。


这是一个测试工具:

$ touch {1..19}.jpg

$ ls
10.jpg  12.jpg  14.jpg  16.jpg  18.jpg  1.jpg  3.jpg  5.jpg  7.jpg  9.jpg
11.jpg  13.jpg  15.jpg  17.jpg  19.jpg  2.jpg  4.jpg  6.jpg  8.jpg

$ rename 's/\d+/sprintf("%05d", $&)/e' *.jpg

$ ls
00001.jpg  00005.jpg  00009.jpg  00013.jpg  00017.jpg
00002.jpg  00006.jpg  00010.jpg  00014.jpg  00018.jpg
00003.jpg  00007.jpg  00011.jpg  00015.jpg  00019.jpg
00004.jpg  00008.jpg  00012.jpg  00016.jpg

还有一个前缀示例(我们没有做任何不同的事情):

$ touch track_{9..11}.mp3 && ls
track_10.mp3  track_11.mp3  track_9.mp3

$ rename 's/\d+/sprintf("%02d", $&)/e' *.mp3 && ls
track_09.mp3  track_10.mp3  track_11.mp3

如果我是Perl人士,这将是完美的解决方案。真的很整洁。
MGP

2
它不使用任何perl,仅提供了已经用perl编写的工具。
罗布

1
在这种情况下,它确实涉及单个Perl命令,但并不十分繁琐。sprintfPerl中的行为与sprintf其他语言类似。
奥利(Oli)

21
for f in *.jpg ; do if [[ $f =~ [0-9]+\. ]] ; then  mv $f `printf "%.5d" "${f%.*}"`.jpg  ; fi ; done

编辑

说明:

  • if [[ $f =~ [0-9]+\. ]] 确保仅重命名其名称为数字(后跟点)的文件。
  • printf "%.5d" NUMBER 加前导零
  • "${f%.*}" 剪切扩展名(.jpg),仅保留数字
  • .jpg在第二个反引号之后再次添加文件扩展名。

请注意,这仅适用于数字文件名。左填充前导零到未编号的文件将需要不同的格式。

如果要尝试,请尝试以下命令:

for f in *.jpg ; do if [[ $f =~ [0-9]+\. ]] ; then echo mv $f `printf "%.5d" "${f%.*}"`.jpg  ; fi ; done

编辑2

确保仅重命名数字文件名,从而使命令更安全。请注意,任何名称为00001.jpg之类的现有文件将被覆盖。


这个衬里脚本可以在Ubuntu和其他Linux发行版上“开箱即用”!😃无需使用Perl,Python和等安装任何额外的工具
HEXcube

6

在python脚本下面。

该脚本将前导零添加到所定义的位数。如果名称大于该名称,则文件(名称)保持不变。

在一个重命名操作中组合不同的扩展名可能会增加一些便利。要添加扩展,只需将其添加到元组,例如extensions = (".jpg", ".jpeg", ".tiff")

将文本复制到一个空文件中,另存为rename.py,输入文件目录的正确路径(sourcedir),您希望新名称具有的位数(number_ofdigits)和要重命名的文件扩展名(extensions)。

通过以下命令运行它:

python3 /path/to/script/rename.py

剧本:

#!/usr/bin/python3

import shutil
import os

sourcedir = "/path/to/files"; number_ofdigits = 5; extensions = (".jpg", ".jpeg")

files = os.listdir(sourcedir)
for item in files:
    if item.endswith(extensions):
        name = item.split("."); zeros = number_ofdigits-len(name[0])
        newname = str(zeros*"0")+name[0]+"."+name[1]
        shutil.move(sourcedir+"/"+item, sourcedir+"/"+newname)

编辑:

下面略有改进的版本。它会自动确定目录中最长的名称,并将前导零添加到最长名称的长度。

例:

1.jpg
12.jpg
123.jpg

变成:

001.jpg
012.jpg
123.jpg

无需设置位数。

#!/usr/bin/python3

import shutil
import os

sourcedir = "/path/to/files"; extensions = (".jpg", ".jpeg")
files = [(f, f[f.rfind("."):], f[:f.rfind(".")]) for f in os.listdir(sourcedir)if f.endswith(extensions)]
maxlen = len(max([f[2] for f in files], key = len))

for item in files:
    zeros = maxlen-len(item[2])
    shutil.move(sourcedir+"/"+item[0], sourcedir+"/"+str(zeros*"0")+item[0])

2

Perl中实现了一个重命名实用程序,这使此操作非常容易:

rename 's/\d+/sprintf("%05d",$&)/e' *.jpg

第一个参数是为每个文件名求值的Perl表达式。


0

有一个可以执行此操作的GUI,称为pyRenamer,可以在存储库中找到它。安装,开始,选择目录,然后在“模式”选项卡上将“重命名的文件名模式”设置为“ {num5}”,然后单击“重命名”按钮。您还可以预览重命名之前会发生的情况。


尽管您的答案确实可行,但是请注意,这是一个shell-scripting部分,表示我正在寻找命令行答案。另外,您能否提供有关该程序的更多详细信息?例如,什么是格式格式{num5}
卡兹·沃尔夫

-4
for file in `(find * -maxdepth 1 -type f -name "*.jpg")`     
do    
  mv $file "000"$file    
done

这很粗糙,因为它不能智能地进行重命名,因此需要考虑一个技巧。但这应该可以帮助您对内容进行分类。

更新:那么您有一个更完整的答案。


2
它将1439.jpg重命名为0001439.jpg。
Avinash Raj 2014年

是的,我知道,只需填充额外的零,这些零仍应与排序配合使用。
Swarnendu Biswas
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.