使用python批量重命名100K文件

Posted

技术标签:

【中文标题】使用python批量重命名100K文件【英文标题】:batch renaming 100K files with python 【发布时间】:2011-03-05 21:39:17 【问题描述】:

我有一个包含超过 100,000 个文件的文件夹,所有文件都使用相同的存根编号,但没有前导零,并且数字并不总是连续的(通常它们是连续的,但有间隔)例如:

file-21.png, 
file-22.png,  
file-640.png, 
file-641.png, 
file-642.png, 
file-645.png, 
file-2130.png, 
file-2131.png, 
file-3012.png, 

等等

我想对此进行批处理以创建填充的连续文件。例如:

file-000000.png, 
file-000001.png, 
file-000002.png, 
file-000003.png, 

当我使用for filename in os.listdir('.'): 解析文件夹时,文件并没有按照我想要的顺序出现。可以理解的是他们出现了

 file-1, 
 file-1x, 
 file-1xx, 
 file-1xxx,

等等。那么

 file-2, 
 file-2x, 
 file-2xx, 

等等。我怎样才能让它按数值的顺序通过?我是一个完整的 python 菜鸟,但是查看文档我猜我可以使用 map 创建一个新列表,只过滤掉数字部分,然后对该列表进行排序,然后迭代它?对于超过 100K 的文件,这可能很重。欢迎任何提示!

【问题讨论】:

你可以运行一个带有任意数量参数的 linux "ls" 命令来按你想要的方式对它们进行排序......然后使用这个列表来获取文件。 是的,如果我这样做,我会使用sort -n 与其用答案编辑您的问题,不如将您的解决方案作为自己的答案发布在底部并将其标记为已接受。 【参考方案1】:
import re
thenum = re.compile('^file-(\d+)\.png$')

def bynumber(fn):
  mo = thenum.match(fn)
  if mo: return int(mo.group(1))

allnames = os.listdir('.')
allnames.sort(key=bynumber)

现在你已经按照你想要的顺序获得了文件,并且可以循环播放

for i, fn in enumerate(allnames):
  ...

使用渐进式数字i(将是 0、1、2、...)在目的地名称中随心所欲地填充。

【讨论】:

也许更快的排序函数是 def bynumber(fn): return int(filter(str.isdigit, fn)) 是的,如果您确定在任何地方都没有“杂散”数字,它会更快(我基于 RE 的解决方案也会检查,如果有人“知道”它总是每次都成功,那么检查的纯开销; -)。【参考方案2】:

分为三个步骤。首先是获取所有文件名。第二个是转换文件名。三是重命名。

如果所有文件都在同一个文件夹中,那么 glob 应该可以工作。

import glob
filenames = glob.glob("/path/to/folder/*.txt")

接下来,您要更改文件的名称。您可以使用填充打印来执行此操作。

>>> filename = "file-338.txt"
>>> import os
>>> fnpart = os.path.splitext(filename)[0]
>>> fnpart
'file-338'
>>> _, num = fnpart.split("-")
>>> num.rjust(5, "0")
'00338'
>>> newname = "file-%s.txt" % num.rjust(5, "0")
>>> newname
'file-00338.txt'

现在,您需要将它们全部重命名。 os.rename 就是这样做的。

os.rename(filename, newname)

把它放在一起:

for filename in glob.glob("/path/to/folder/*.txt"): # loop through each file
    newname = make_new_filename(filename) # create a function that does step 2, above
    os.rename(filename, newname)

【讨论】:

这忽略了原始文件名中跳过数字的问题 - 请参阅我的答案以了解如何轻松修复它!【参考方案3】:

谢谢大家的建议,我会尝试他们来学习不同的方法。我采用的解决方案是基于在我的文件列表上使用自然排序,然后对其进行迭代以重命名。这是建议的答案之一,但由于某种原因它现在消失了,所以我无法将其标记为已接受!

import os
files = os.listdir('.')
natsort(files)
index = 0
for filename in files:
    os.rename(filename, str(index).zfill(7)+'.png')
    index += 1

natsort 在http://code.activestate.com/recipes/285264-natural-string-sorting/ 中定义

【讨论】:

【参考方案4】:

为什么不分两步进行。解析所有文件并用填充数字重命名,然后运行另一个脚本来获取这些文件,这些文件现在已正确排序,并重命名它们以使它们连续?

【讨论】:

重命名操作(系统调用)将成为瓶颈:执行两倍的操作将花费两倍的时间。请参阅我的答案以获得快速的方法(每个文件一个重命名)。 你会在内存中重命名它们,你不会以这种方式将它们写回磁盘。所以只写一篇。【参考方案5】:

1) 取文件名中的数字。 2)用零填充它 3) 保存名称。

【讨论】:

这忽略了数字上的差距。【参考方案6】:
def renamer():
    for iname in os.listdir('.'):
        first, second = iname.replace(" ", "").split("-")
        number, ext = second.split('.')
        first, number, ext = first.strip(), number.strip(), ext.strip()
        number = '0'*(6-len(number)) + number  # pad the number to be 7 digits long
        oname = first + "-" + number + '.' + ext
        os.rename(iname, oname)
    print "Done"

希望对你有帮助

【讨论】:

谢谢,据我了解,这只会填充现有数字,不会使序列连续无间隙?

以上是关于使用python批量重命名100K文件的主要内容,如果未能解决你的问题,请参考以下文章

Python批量重命名 记录贴

[经典] 使用Python批量重命名iPhone拍摄的照片-按照拍摄时间重命名

python 批量重命名文件后缀

Python 批量重命名

Python对文件进行批量重命名

利用Python对文件进行批量重命名——以图片文件为例