Вопрос

I read out of the XML-files their category and I rename and save them with the year. So, file "XYZ.xml" is now "News_2014.xml".

The Problem is that there are several XML-files with the category "News" from 2014. With my code, I delete all other files and I can save only 1 file. What can I do in order that every file is saved? For example, if there are 2 files with the category "News" and the Year 2014, there file-names should be: "News_2014_01.xml" and "News_2014_02.xml".

Since there are other categories, I can not simply implement an increasing integer, i.e. another file with the category "History" should still have the Name "History_2014_01.xml" (and not ...03.xml).

Actually, I have the following code:

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') 
Это было полезно?

Решение

Once you have figured out the “correct” name for the file, e.g. News_2014.xml, you could make a loop that checks whether the file exists and adds an incrementing suffix to it while that’s the case:

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)

You can put that into a function, so it’s easier to use:

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

And then use that in your code:

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)

Другие советы

[EDIT] @poke solution is much more elegant, let alone he posted it earlier

You can check if target filename already exists, and if it does, modify filename. The easiest solution for me would be to always start with adding 'counter' to file name, so you start with News_2014_000.xml (maybe better be prepared for more than 100 files?).

Later you loop until you find filename, that does not exist:

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

So, if you want to save as 'News_2014_###.xml' file you can create name as usual, but call os.rename(sourcename, versioned_filename(targetname)). If you want more efficient solution, you can parse output of glob.glob() to find highest count, you will save on multiple calling to os.path.exists, but it makes sense only if you expect hundreds or thousands of files.

You could use a dictionary to keep track of the count. That way, there is no need to modify file names after you've renamed them. The downside is that every filename will have a number in it, even if the max number for that category ends up being 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]))
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top