简体   繁体   English

python os.rename模块删除文件

[英]python os.rename module deletes files

I've wrote a little program to rename a big bunch of files in python 我写了一个小程序来重命名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:])

It reads the names out of a txt-file which is given as an argument and renames the other avi files. 它从txt文件中读取名称,该文件作为参数给出并重命名其他avi文件。 But there was one file missing with the start number '102' so now the complete order from '102' on is wrong. 但是有一个文件缺少,起始编号为'102',所以现在从'102'开始的完整订单是错误的。 If I now rerun this file and delete the line 102 in my txt file every file from 102 on is deleted except the last one. 如果我现在重新运行此文件并删除我的txt文件中的第102行,则除了最后一个文件之外,其他每个文件都将被删除。
May you know how to fix this little bug and can explain to me how this happens because I work on this far too long. 你可以知道如何修复这个小bug,并向我解释这是怎么发生的,因为我的工作时间太长了。

---Edit--- - -编辑 - -

A short snippet of my text file 我的文本文件的一小段

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

The list goes on up to 400. I've got 300 files so the problem with os.rename won't happen. 该列表最多可达400个。我有300个文件,因此os.rename的问题不会发生。 The file with the number 102 didn't exist when i first ran the script, so everything above is one number wrong. 第一次运行脚本时,编号为102的文件不存在,因此上面的所有内容都是错误的。 I added the file 102 and want to rerun this script. 我添加了文件102并想重新运行此脚本。

The files before I rerun: 我重新运行之前的文件:

...
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
... 

The files afterwards: 之后的文件:

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

If you need any more information I will provide it as well as possible 如果您需要更多信息,我会尽可能提供

Ok. 好。 I figured the problem out thanks to Corley. 考虑到科利,我想出了问题。 When i rerun the program with the one entry of the missing file deleted I get double names which will delete the files as Corley described. 当我重新运行程序时删除了丢失文件的一个条目,我得到双重名称,这将删除Corley描述的文件。 I fixed this with a loop which renames all my files to simple number 我用一个循环修复它,它将我的所有文件重命名为简单数字

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

and so on. 等等。 Then i rename the files like they should be with the script in my initial question. 然后我在我的初始问题中重命名文件,就像它们应该与脚本一样。

Thanks for helping me figure it out. 谢谢你帮我搞清楚。

You probably have fewer lines in your file than you have files in the directory. 您的文件中的行可能比目录中的文件少。 I'm guessing this is a unix environment? 我猜这是一个unix环境?

readline has this side effect, from the docs: readline有这种副作用,来自docs:

f.readline() reads a single line from the file; f.readline()从文件中读取一行; a newline character (\\n) is left at the end of the string, and is only omitted on the last line of the file if the file doesn't end in a newline. 换行符(\\ n)留在字符串的末尾,如果文件没有以换行符结尾,则只在文件的最后一行省略。 This makes the return value unambiguous; 这使得返回值明确无误; if f.readline() returns an empty string, the end of the file has been reached, while a blank line is represented by '\\n', a string containing only a single newline. 如果f.readline()返回一个空字符串,则表示已到达文件的末尾,而空行由'\\ n'表示,该字符串仅包含一个换行符。

os.rename has this side effect, from the docs: os.rename从文档中有这种副作用:

On Unix, if dst exists and is a file, it will be replaced silently if the user has permission. 在Unix上,如果dst存在且是一个文件,如果用户有权限,它将被静默替换。

You can probably guess what's going wrong by now, but i'll spell it out just in case: 你现在可以猜到出了什么问题,但为了以下情况,我会拼出来:

Let's say you have 5 files in your directory: 假设您的目录中有5个文件:

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

And in your input file, you only have 3 entries: 在输入文件中,您只有3个条目:

User1
User2
User3

The expectation is that you want a.txt renamed to User1.txt , etc. Though, it's all implicit of course. 期望是你想要a.txt重命名为User1.txt等等。虽然,它当然是隐含的。

So, your script will rename a.txt to User1.txt , then b.txt to User2.txt , then c.txt to User3.txt . 所以,你的脚本将重命名a.txtUser1.txt ,然后b.txtUser2.txt ,然后c.txtUser3.txt

What happens for d.txt ? d.txt会发生什么? It will read the file, and get an empty string. 它将读取文件,并获得一个空字符串。 It will then add the original extension onto the file, and rename d.txt to .txt . 然后,它会将原始扩展名添加到文件中,并将d.txt重命名为.txt Not very useful. 不是很有用。

It gets worse... now, we look at e.txt . 它变得更糟......现在,我们来看看e.txt It will read the file again with readline() and get another empty string. 它将使用readline()再次读取文件并获取另一个空字符串。 It will then again add the original extension onto the file, and rename e.txt to .txt . 然后它会再次将原始扩展名添加到文件中,并将e.txt重命名为.txt Since there's already a file with that name, it gets deleted and now d.txt just disappears altogether. 由于已经存在具有该名称的文件,因此它将被删除,现在d.txt完全消失。

This is the script I use to batch rename my files, ensuring that no files are deleted when I run it. 这是我用来批量重命名文件的脚本,确保在运行时不删除任​​何文件。 It first renames any .wav file in a folder to another folder I created called "temp" with a UUID. 它首先将文件夹中的任何.wav文件重命名为我创建的另一个名为“temp”的文件夹,其中包含UUID。 Then, it renames the files back to the target folder and names them whatever the folder name is plus a sequential number starting at 0. 然后,它将文件重命名回目标文件夹,并将其命名为文件夹名称加上从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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM