Python:重命名文件
我从XML文件中读取它们的类别,然后把它们重命名并保存上年份。比如,文件“XYZ.xml”现在变成了“News_2014.xml”。
问题是,有好几个2014年的XML文件都是“News”类别。我的代码只保留一个文件,其他的都被删除了。我该怎么做才能保存每个文件呢?比如,如果有两个类别为“News”且年份为2014的文件,它们的文件名应该是:“News_2014_01.xml”和“News_2014_02.xml”。
因为还有其他类别,所以我不能简单地用一个递增的数字来命名。比如,另一个类别为“History”的文件仍然应该叫“History_2014_01.xml”(而不是...03.xml)。
实际上,我现在有以下代码:
for text, key in enumerate(d):
#print key, d[key]
name = d[key][(d[key].find("__")+2):(d[key].rfind("__"))]
year = d[key][(d[key].find("*")+1):(d[key].rfind("*"))]
cat = d[key][(d[key].rfind("*")+1):]
os.rename(name, cat+"_"+year+'.xml')
3 个回答
你可以用一个字典来记录计数。这样的话,重命名文件后就不需要再去修改文件名了。不过缺点是,每个文件名里都会有一个数字,即使那个类别的最大数字最后只有 1
。
cat_count = {}
for text, key in enumerate(d):
name = d[key][(d[key].find("__")+2):(d[key].rfind("__"))]
year = d[key][(d[key].find("*")+1):(d[key].rfind("*"))]
cat = d[key][(d[key].rfind("*")+1):]
cat_count[cat] = cat_count[cat] + 1 if cat in cat_count else 1
os.rename(name, "%s_%s_%02d.xml" % (cat, year, cat_count[cat]))
[编辑] @poke 的解决方案更优雅,而且他还早早就发出来了。
你可以先检查一下目标文件名是否已经存在,如果存在,就修改文件名。对我来说,最简单的办法就是在文件名里加上一个“计数器”,比如你可以从 News_2014_000.xml 开始(也许要准备好处理超过100个文件?)。
然后你可以循环查找,直到找到一个不存在的文件名:
def versioned_filename(candidate):
target = candidate
while os.path.exists(target):
fname, ext = target.rsplit('.', 1)
head, tail = fname.rsplit('_', 1)
count = int(tail)
#:03d formats as 3-digit with leading zero
target = "{}_{:03d}.{}".format(head, count+1, ext)
return target
所以,如果你想保存为 'News_2014_###.xml' 这样的文件,你可以像往常一样创建文件名,但要调用 os.rename(sourcename, versioned_filename(targetname))
。如果你想要更高效的解决方案,可以解析 glob.glob()
的输出,找到最大的计数,这样你就能减少多次调用 os.path.exists 的次数,但这只有在你预期会有成百上千个文件时才有意义。
一旦你找到了文件的“正确”名字,比如说 News_2014.xml
,你可以写一个循环来检查这个文件是否存在。如果文件存在,就在文件名后面加一个递增的后缀,直到找到一个不存在的文件名为止:
import os
fileName = 'News_2014.xml'
baseName, extension = os.path.splitext(fileName)
suffix = 0
while os.path.exists(os.path.join(directory, fileName)):
suffix += 1
fileName = '{}_{:02}.{}'.format(baseName, suffix, extension)
print(fileName)
os.rename(originalName, fileName)
你可以把这个过程放到一个函数里,这样使用起来会更方便:
def getIncrementedFileName (fileName):
baseName, extension = os.path.splitext(fileName)
suffix = 0
while os.path.exists(os.path.join(directory, fileName)):
suffix += 1
fileName = '{}_{:02}.{}'.format(baseName, suffix, extension)
return fileName
然后在你的代码中使用这个函数:
for key, item in d.items():
name = item[item.find("__")+2:item.rfind("__")]
year = item[item.find("*")+1:item.rfind("*")]
cat = item[item.rfind("*")+1:]
fileName = getIncrementedFileName(cat + '_' + year + '.xml')
os.rename(name, fileName)