Python重命名文件很奇怪

时间:2014-09-15 01:00:10

标签: python python-3.x

我有这个功能:

def rename(path):
    """ Renames all the files to be cropped-%d.xxx """
    count = 0
    for thing in os.listdir(path):
        root, ext = os.path.splitext(thing)
        os.rename(os.path.join(path, thing), os.path.join(path, sys.argv[1]+".cropped{0}".format(count)+ext))
        count += 1

这样可行,但是如果我在已经运行它的目录上运行它,它似乎删除了其重命名的一半文件。为什么会这样?

2 个答案:

答案 0 :(得分:3)

如果您打印出您正在进行的重命名,则更容易看到发生了什么:

def rename(path):
    """ Renames all the files to be cropped-%d.xxx """
    count = 0 
    for thing in os.listdir(path):
        root, ext = os.path.splitext(thing)
        old = os.path.join(path, thing)
        new = os.path.join(path, sys.argv[1] + ".cropped{0}".format(count) + ext)
        print("rename from {} to {}".format(old, new))
        os.rename(old, new)
        count += 1

此处的示例输出运行两次:

dan@dandesk:~$ python ok.py b
rename from test/4.txt to test/b.cropped0.txt
rename from test/2.txt to test/b.cropped1.txt
rename from test/5.txt to test/b.cropped2.txt
rename from test/7.txt to test/b.cropped3.txt
rename from test/1.txt to test/b.cropped4.txt
rename from test/3.txt to test/b.cropped5.txt
rename from test/6.txt to test/b.cropped6.txt
dan@dandesk:~$ python ok.py b
rename from test/b.cropped3.txt to test/b.cropped0.txt
rename from test/b.cropped4.txt to test/b.cropped1.txt
rename from test/b.cropped2.txt to test/b.cropped2.txt
rename from test/b.cropped5.txt to test/b.cropped3.txt
rename from test/b.cropped1.txt to test/b.cropped4.txt
rename from test/b.cropped0.txt to test/b.cropped5.txt
rename from test/b.cropped6.txt to test/b.cropped6.txt

现在这里是测试目录内容:

dan@dandesk:~$ ls -1 test
b.cropped2.txt
b.cropped3.txt
b.cropped4.txt
b.cropped5.txt
b.cropped6.txt

如您所见,b.cropped1.txtb.cropped0.txt已经消失。上面的输出揭示了原因:

rename from test/b.cropped3.txt to test/b.cropped0.txt
rename from test/b.cropped4.txt to test/b.cropped1.txt
...
rename from test/b.cropped1.txt to test/b.cropped4.txt
rename from test/b.cropped0.txt to test/b.cropped5.txt

我们将两个文件重命名为缺少的名称,然后再将其重命名为 ,这意味着我们会丢失b.cropped4.txtb.cropped5.txt中的任何内容。

您可以通过确保您将要使用的新名称已经存在来避免这种情况,如果确实存在,请增加count,直到您获得的文件不存在为止。存在:

def rename(path):
    """ Renames all the files to be cropped-%d.xxx """
    count = 0
    for thing in os.listdir(path):
        root, ext = os.path.splitext(thing)
        old = os.path.join(path, thing)
        while True:
            new = os.path.join(path, sys.argv[1] + ".cropped{0}".format(count) + ext)
            if not os.path.exists(new):
                break
            count += 1
        print("rename from {} to {}".format(old, new))
        os.rename(old, new)
        count += 1

输出:

dan@dandesk:~$ python ok.py b
rename from test/4.txt to test/b.cropped0.txt
rename from test/2.txt to test/b.cropped1.txt
rename from test/5.txt to test/b.cropped2.txt
rename from test/1.txt to test/b.cropped3.txt
rename from test/3.txt to test/b.cropped4.txt
rename from test/6.txt to test/b.cropped5.txt
dan@dandesk:~$ python ok.py b
rename from test/b.cropped3.txt to test/b.cropped6.txt
rename from test/b.cropped4.txt to test/b.cropped7.txt
rename from test/b.cropped2.txt to test/b.cropped8.txt
rename from test/b.cropped5.txt to test/b.cropped9.txt
rename from test/b.cropped1.txt to test/b.cropped10.txt
rename from test/b.cropped0.txt to test/b.cropped11.txt

答案 1 :(得分:0)

当具有新名称的文件已经存在时会发生这种情况,因此您要用重命名的文件替换现有文件,在此过程中丢失原始文件。