Python:重命名文件

2 投票
3 回答
804 浏览
提问于 2025-04-17 21:31

我从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

你可以用一个字典来记录计数。这样的话,重命名文件后就不需要再去修改文件名了。不过缺点是,每个文件名里都会有一个数字,即使那个类别的最大数字最后只有 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]))
1

[编辑] @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 的次数,但这只有在你预期会有成百上千个文件时才有意义。

2

一旦你找到了文件的“正确”名字,比如说 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)

撰写回答