Reputation: 851
So i'm trying to rename a list of files with set renames like so:
import os
import time
for fileName in os.listdir("."):
os.rename(fileName, fileName.replace("0001", "00016.5"))
os.rename(fileName, fileName.replace("0002", "00041"))
os.rename(fileName, fileName.replace("0003", "00042"))
...
but that gives me this error os.rename(fileName, fileName.replace("0002", "00041"))``OSError: [Errno 2] No such file ordirectory
(the file is in the directory)
So next i tried
import os
import time
for fileName in os.listdir("."):
os.rename(fileName, fileName.replace("0001", "00016.5"))
for fileName in os.listdir("."):
os.rename(fileName, fileName.replace("0002", "00041"))
for fileName in os.listdir("."):
os.rename(fileName, fileName.replace("0003", "00042"))
...
But that renames the files very strangely with a lot on extra characters, what im i doing wrong here?
Upvotes: 0
Views: 75
Reputation: 18136
listdir returns all object's names (files, directories, ...) not a full path. You can construct a full path using: os.path.join(). Your for loop renames, all found objects first to 00016.5, then to 00041 ...
One way to rename the files, could the following:
import os
import time
currentDir = os.pathdirname(__file__)
for fileName in os.listdir(currentDir):
if '0001' in fileName:
oldPath = os.path.join(currentDir, fileName)
newPath = os.path.join(currentDir, fileName.replace("0001", "00016.5"))
elif '0002' in fileName:
oldPath = os.path.join(currentDir, fileName)
newPath = os.path.join(currentDir, fileName.replace("0002", "00041"))
else:
continue
os.rename(oldPath, newPath)
Upvotes: 1
Reputation: 140286
The fact that multi-pass renaming works while single pass renaming doesn't means that some of your files contain the 0001
pattern as well as 0002
pattern.
So when doing only one loop, you're renaming files but you're given the old list of files (listdir
returns a list
, so it's outdated as soon as you rename a file) => some source files cannot be found.
When doing in multi-pass, you're applying multiple renames on some files.
That could work (and is more compact):
for fileName in os.listdir("."):
for before,after in (("0001", "00016.5"),("0002", "00041"),("0003", "00042")):
if os.path.exists(fileName):
newName = fileName.replace(before,after)
# file hasn't been renamed: rename it (only if different)
if newName != fileName:
os.rename(fileName,newName)
basically I won't rename a file if it doesn't exist (which means it has been renamed in a previous iteration). So there's only one renaming possible. You just have to prioritize which one.
Upvotes: 1