使用Python批量重命名10万文件
我有一个文件夹,里面有超过10万个文件,所有文件的名字都是相同的前缀,后面跟着数字,但这些数字没有前导零,并且数字之间并不是连续的(通常是连续的,但中间会有空缺),比如:
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来创建一个新列表,只保留数字部分,然后对这个列表进行排序,再进行遍历?不过有超过10万个文件,这样处理可能会很耗资源。欢迎任何建议!
7 个回答
这个过程分为三个步骤。第一步是获取所有的文件名。第二步是转换这些文件名。第三步是给它们重新命名。
如果所有的文件都在同一个文件夹里,那么使用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)
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, ...),并根据你的需要在目标名称中添加前导零。
谢谢大家的建议,我会尝试所有的方法来学习不同的做法。我选择的解决方案是对我的文件列表进行自然排序,然后逐个重命名。这是其中一个建议的答案,但不知道为什么现在消失了,所以我无法标记它为已接受的答案!
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/ 找到。