Renaming multiple files - python

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?

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.

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)

Related

remove characters from every file name in directory with python

So I am writing a piece of code that needs to iterate through hundreds of files in a directory. With every filt it needs to filter out certain pieces of information in it then put it in a new file with a modified name.
For example, a file called 1100006_0.vcf or 5100164_12.vcf must have a file created called 1100006.vcf and 5100164.vcf respectively. Can you point me in the right direction for this?
EDIT: To make code Generic and rename file names from one directory to any other directory/folder try following. I have kept this program inside /tmp and renamed the files inside /tmp/test and it worked fine(in a Linux system).
#!/usr/bin/python3
import os
DIRNAME="/tmp/test"
files = os.listdir(DIRNAME)
for f in files:
if '.vcf' in f:
newname = f.split('_')[0]
newname = newname + '.vcf'
os.rename(os.path.join(DIRNAME,f), os.path.join(DIRNAME,newname))
Since you want to rename the files, so we could use os here. Written and tested with shown samples in python3, I have given DIRNAME as /tmp you could give your directory where you want to look for files.
#!/usr/bin/python3
import os
DIRNAME="/tmp"
files = os.listdir(DIRNAME)
for f in files:
if '.vcf' in f:
newname = f.split('_')[0]
newname = newname + '.vcf'
os.rename(f, newname)
As posted by RavinderSingh13, the code was fine, the only issue was that in renaming them, I would have two files of the same name (the difference between them was the underscore and number that I needed removed).
#!/usr/bin/python3
import os
DIRNAME="/tmp"
files = os.listdir(DIRNAME)
for f in files:
if '.vcf' in f:
newname = f.split('_')[0]
newname = newname + '.vcf'
os.rename(f, newname)

Keeping renamed text files in original folder

This is my current (from a Jupyter notebook) code for renaming some text files.
The issue is when I run the code, the renamed files are placed in my current working Jupyter folder. I would like the files to stay in the original folder
import glob
import os
path = 'C:\data_research\text_test\*.txt'
files = glob.glob(r'C:\data_research\text_test\*.txt')
for file in files:
os.rename(file, file[-27:])
You should only change the name and keep the path the same. Your filename will not always be longer than 27 so putting this into you code is not ideal. What you want is something that just separates the name from the path, no matter the name, no matter the path. Something like:
import os
import glob
path = 'C:\data_research\text_test\*.txt'
files = glob.glob(r'C:\data_research\text_test\*.txt')
for file in files:
old_name = os.path.basename(file) # now this is just the name of your file
# now you can do something with the name... here i'll just add new_ to it.
new_name = 'new_' + old_name # or do something else with it
new_file = os.path.join(os.path.dirname(file), new_name) # now we put the path and the name together again
os.rename(file, new_file) # and now we rename.
If you are using windows you might want to use the ntpath package instead.
file[-27:] takes the last 27 characters of the filename so unless all of your filenames are 27 characters long, it will fail. If it does succeed, you've stripped off the target directory name so the file is moved to your current directory. os.path has utilities to manage file names and you should use them:
import glob
import os
path = 'C:\data_research\text_test*.txt'
files = glob.glob(r'C:\data_research\text_test*.txt')
for file in files:
dirname, basename = os.path.split(file)
# I don't know how you want to rename so I made something up
newname = basename + '.bak'
os.rename(file, os.path.join(dirname, newname))

Trying renaming all files in a folder

I am trying the script below to rename all files in a folder.It is working fine,But when i am trying to run it outside the folder.It shows error.
import os
path=os.getcwd()
path=os.path.join(path,'it')
filenames = os.listdir(path)
i=0
for filename in filenames:
os.rename(filename, "%d.jpg"%i)
i=i+1
'it' is the name of the folder in which files lie.
Error:FileNotFoundError: [Errno 2] No such file or directory: '0.jpg' -> '0.jpg'
Print is showing names of files
When you do os.listdir(path) you get the filenames of files in the folder, but not the complete paths to those files. When you call os.rename you need the path to the file rather than just the filename.
You can join the filename to its parent folder's path using os.path.join.
E.g. os.path.join(path, file).
Something like this might work:
for filename in filenames:
old = os.path.join(path, filename)
new = os.path.join(path, "%d.jpg"%i)
os.rename(old, new)
i=i+1
You need to mention complete or relative path to file.
In this case, it should be
path + '/' + filename
or more generally,
newpath = os.path.join(path, filename)

renaming files in a directory + subdirectories in python

I have some files that I'm working with in a python script. The latest requirement is that I go into a directory that the files will be placed in and rename all files by adding a datestamp and project name to the beginning of the filename while keeping the original name.
i.e. foo.txt becomes 2011-12-28_projectname_foo.txt
Building the new tag was easy enough, it's just the renaming process that's tripping me up.
Can you post what you have tried?
I think you should just need to use os.walk with os.rename.
Something like this:
import os
from os.path import join
for root, dirs, files in os.walk('path/to/dir'):
for name in files:
newname = foo + name
os.rename(join(root,name),join(root,newname))
I know this is an older post of mine, but seeing as how it's been viewed quite a few times I figure I'll post what I did to resolve this.
import os
sv_name="(whatever it's named)"
today=datetime.date.today()
survey=sv_name.replace(" ","_")
date=str(today).replace(" ","_")
namedate=survey+str(date)
[os.rename(f,str(namedate+"_"+f)) for f in os.listdir('.') if not f.startswith('.')]
import os
dir_name = os.path.realpath('ur directory')
cnt=0 for root, dirs, files in os.walk(dir_name, topdown=False):
for file in files:
cnt=cnt+1
file_name = os.path.splitext(file)[0]#file name no ext
extension = os.path.splitext(file)[1]
dir_name = os.path.basename(root)
try:
os.rename(root+"/"+file,root+"/"+dir_name+extension)
except FileExistsError:
os.rename(root+"/"+file,root+""+dir_name+str(cnt)+extension)
to care if more files are there in single folder and if we need to give incremental value for the files

WindowsError: [Error 2] The system cannot find the file specified

I am having a problem with this code. I am trying to rename all of the filenames within a folder so that they no longer have +'s in them! This has worked many times before but suddenly I get the error:
WindowsError: [Error 2] The system cannot find the file specified at line 26
Line 26 is the last line in the code.
Does anyone know why this is happening? I just promised someone I could do this in 5 minutes because I had a code! Shame it doesnt work!!
import os, glob, sys
folder = "C:\\Documents and Settings\\DuffA\\Bureaublad\\Johan\\10G304655_1"
for root, dirs, filenames in os.walk(folder):
for filename in filenames:
filename = os.path.join(root, filename)
old = "+"
new = "_"
for root, dirs, filenames in os.walk(folder):
for filename in filenames:
if old in filename:
print (filename)
os.rename(filename, filename.replace(old,new))
I suspect that you may be having issues with subdirectories.
If you have a directory with files "a", "b" and subdirectory "dir" with files "sub+1" and "sub+2", the call to os.walk() will yield the following values:
(('.',), ('dir',), ('a', 'b'))
(('dir',), (,), ('sub+1', 'sub+2'))
When you process the second tuple, you will call rename() with 'sub+1', 'sub_1' as the arguments, when what you want is 'dir\sub+1', 'dir\sub_1'.
To fix this, change the loop in your code to:
for root, dirs, filenames in os.walk(folder):
for filename in filenames:
filename = os.path.join(root, filename)
... process file here
which will concatenate the directory with the filename before you do anything with it.
Edit:
I think the above is the right answer, but not quite the right reason.
Assuming you have a file "File+1" in the directory, os.walk() will return
("C:/Documents and Settings/DuffA/Bureaublad/Johan/10G304655_1/", (,), ("File+1",))
Unless you are in the "10G304655_1" directory, when you call rename(), the file "File+1" will not be found in the current directory, as that is not the same as the directory os.walk() is looking in. By doing the call to os.path.join() yuo are telling rename to look in the right directory.
Edit 2
A example of the code required might be:
import os
# Use a raw string, to reduce errors with \ characters.
folder = r"C:\Documents and Settings\DuffA\Bureaublad\Johan\10G304655_1"
old = '+'
new = '_'
for root, dirs, filenames in os.walk(folder):
for filename in filenames:
if old in filename: # If a '+' in the filename
filename = os.path.join(root, filename) # Get the absolute path to the file.
print (filename)
os.rename(filename, filename.replace(old,new)) # Rename the file
You are using splitext to determine the source filename to rename:
filename_split = os.path.splitext(filename) # filename and extensionname (extension in [1])
filename_zero = filename_split[0]#
...
os.rename(filename_zero, filename_zero.replace('+','_'))
If you encounter a file with an extension, obviously, trying to rename the filename without the extension will lead to a "file not found" error.

Categories

Resources