【问题标题】:python os.rename module deletes filespython os.rename 模块删除文件
【发布时间】:2014-04-07 14:48:43
【问题描述】:

我写了一个小程序来重命名python中的一大堆文件

#!/usr/local/bin/python3

import os
import glob
import sys

script, arg1 = sys.argv
f = open(arg1)

# Create a filelist using glob
filelist = glob.glob('*.avi')
filelist.sort()

for filename in filelist:
    print(filename)
    # To keep the file ending
    os.rename(filename, f.readline()[:-1]+filename[-4:])

它从作为参数给出的 txt 文件中读取名称,并重命名其他 avi 文件。但是缺少一个起始编号为“102”的文件,所以现在从“102”开始的完整顺序是错误的。如果我现在重新运行此文件并删除我的txt 文件中的第 102 行,则从 102 开始的每个文件都将被删除,除了最后一个。
希望您知道如何修复这个小错误,并可以向我解释这是如何发生的,因为我在这个问题上工作的时间太长了。

---编辑---

我的文本文件的简短 sn-p

snip
099. Abenteuer in Ido 
100. Corsa, der junge Rebell 
101. Unser Papa ist ein Held 
102. Die Gesetze des Vertrauens 
103. Um acht in Spider's Cafe 
104. Ruffy gegen Vivi 
105. Aufruhr in Rainbase 
snip

列表最多有 400 个。我有 300 个文件,因此不会发生 os.rename 的问题。当我第一次运行脚本时,编号为 102 的文件不存在,所以上面的所有内容都是一个数字错误。我添加了文件 102 并想重新运行此脚本。

我重新运行之前的文件:

...
100. Corsa, der junge Rebell.avi 
101. Unser Papa ist ein Held.avi 
102. Die Gesetze des Vertrauens.avi 
103. Um acht in Spider's Cafe.avi 
104. Ruffy gegen Vivi.avi 
105. Aufruhr in Rainbase.avi
... 

之后的文件:

...
100. Corsa, der junge Rebell.avi 
101. Unser Papa ist ein Held.avi 
301. Sogeking, der Held der Stunde.avi
... 

如果您需要更多信息,我会尽快提供

【问题讨论】:

  • 我不太明白这个问题。您能否提供文本文件的内容、运行脚本之前存在的 avi 文件列表以及之后存在的 avi 文件列表?
  • 是的,您使用的列表会很有帮助。
  • 作为初学者,在您点击此行之前:os.rename(filename, f.readline()[:-1]+filename[-4:]) 我将添加以下调试语句:temp=f.readline() print filename,(temp + filename[-4:]) 这将帮助您了解正在处理的文件名

标签: python file operating-system file-rename


【解决方案1】:

好的。多亏了 Corley,我才解决了这个问题。当我重新运行程序并删除丢失文件的一个条目时,我会得到双重名称,这将删除 Corley 描述的文件。我用一个循环修复了这个问题,将我的所有文件重命名为简单的数字

i = 1
for filename in filelist:
    os.rename(filename, str(i).zfill(4)+'temp'+filename[-4:])
    i+=1
  • 001.temp.avi
  • 002.temp.avi
  • 003.temp.avi
  • ...

等等。然后我重命名文件,就像我最初的问题中的脚本一样。

感谢您帮助我解决问题。

【讨论】:

    【解决方案2】:

    文件中的行数可能少于目录中的文件数。 我猜这是一个unix环境?

    readline 有这个副作用,来自文档:

    f.readline() 从文件中读取一行;换行符 (\n) 留在字符串的末尾,仅在最后一个省略 如果文件不以换行符结尾,则为文件的行。这使得 返回值明确;如果f.readline() 返回一个空字符串,则 已到达文件末尾,而空行表示为 '\n',一个只包含一个换行符的字符串。

    os.rename 有这个副作用,来自文档:

    在 Unix 上,如果 dst 存在并且是一个文件,如果 用户有权限。

    您现在可能已经猜到出了什么问题,但我会拼出来以防万一:

    假设您的目录中有 5 个文件:

    • a.txt
    • b.txt
    • c.txt
    • d.txt
    • e.txt

    在您的输入文件中,您只有 3 个条目:

    User1
    User2
    User3
    

    期望是您希望将a.txt 重命名为User1.txt 等。当然,这都是隐含的。

    因此,您的脚本会将a.txt 重命名为User1.txt,然后将b.txt 重命名为User2.txt,然后将c.txt 重命名为User3.txt

    d.txt 会发生什么?它将读取文件,并获得一个空字符串。然后它将原始扩展名添加到文件中,并将d.txt重命名为.txt。不是很有用。

    情况变得更糟......现在,我们看看e.txt。它将使用readline() 再次读取文件并获得另一个空字符串。然后它将再次将原始扩展名添加到文件中,并将e.txt 重命名为.txt。由于已经有一个同名的文件,它被删除,现在d.txt 完全消失了。

    【讨论】:

      【解决方案3】:

      这是我用来批量重命名文件的脚本,确保运行时不会删除任何文件。它首先将文件夹中的任何 .wav 文件重命名为我创建的另一个文件夹,名为“temp”,带有 UUID。然后,它将文件重命名回目标文件夹,并将它们命名为文件夹名称加上从 0 开始的序号。

      #!/usr/bin/env python
      import os, uuid
      
      path = "/Users/user/Target Folder/A/"
      temp = "/Users/user/temp/"
      ext = ".wav"
      
      # Get directory name
      for path, sub_directories, files in os.walk(path):
          directory_name = os.path.basename(os.path.dirname(path))
      
      # Rename with UUID to temp folder
      for i,filename in enumerate(os.listdir(path)):
          if filename.endswith(ext):
             os.rename(path+filename, temp+str(uuid.uuid4())+ext)
      
      # Rename the files to Folder name plus number
      for i,filename in enumerate(os.listdir(temp)):
          if filename.endswith(ext):
              os.rename(temp+filename, path+directory_name+str(i).zfill(0)+ext)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-01-30
        • 1970-01-01
        • 1970-01-01
        • 2011-08-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多