Renaming filenames using python - python

I need to simply add the word "_Manual" onto the end of all the files i have in a specific directory
Here is the script i am using at the moment - i have no experience with python so this script is a frankenstine of other scripts i had lying around!
It doesn't give any error messages but it also doesnt work..
folder = "C:\Documents and Settings\DuffA\Bureaublad\test"
import os, glob
for root, dirs, filenames in os.walk(folder):
for filename in filenames:
filename_split = os.path.splitext(filename) # filename and extensionname (extension in [1])
filename_zero = filename_split[0]
os.rename(filename_zero, filename_zero + "_manual")
I am now using
folder = "C:\Documents and Settings\DuffA\Bureaublad\test"
import os # glob is unnecessary
for root, dirs, filenames in os.walk(folder):
for filename in filenames:
fullpath = os.path.join(root, filename)
filename_split = os.path.splitext(fullpath) # filename and extensionname (extension in [1])
filename_zero, fileext = filename_split
print fullpath, filename_zero + "_manual" + fileext
os.rename(fullpath, filename_zero + "_manual" + fileext)
but it still doesnt work..
it doesnt print anything and nothing gets changed in the folder!

os.rename requires a source and destination filename. The variable filename contains your current filename (e.g., "something.txt"), whereas your split separates that into something and txt. As the source file to rename, you then only specify something, which fails silently.
Instead, you want to rename the file given in filename, but as you walk into subfolders as well, you need to make sure to use the absolute path. For this you can use os.path.join(root, filename).
So in the end you get something like this:
os.rename(os.path.join(root, filename),
os.path.join(root, filename_zero + "_manual" + filename_split[1]))
This would rename dir1/something.txt into dir1/something_manual.txt.

folder = r"C:\Documents and Settings\DuffA\Bureaublad\test"
import os, glob
for root, dirs, filenames in os.walk(folder):
for filename in filenames:
filename_split = os.path.splitext(filename) # filename and extensionname (extension in [1])
filename_zero = filename_split[0]
os.rename(os.path.join(root, filename), os.path.join(root, filename_zero + "_manual" + filename_split[1]))
In your code, you are trying to rename filename_zero, which is the filename without extension and therefore does not exist as a real path. You have to specify the full path to os.rename like above.

I. e. it does nothing? Let's see:
folder = "C:\Documents and Settings\DuffA\Bureaublad\test"
import os # glob is unnecessary
for root, dirs, filenames in os.walk(folder):
for filename in filenames:
fullpath = os.path.join(root, filename)
filename_split = os.path.splitext(fullpath) # filename and extensionname (extension in [1])
filename_zero, fileext = filename_split
os.rename(fullpath, filename_zero + "_manual" + fileext)
might do the trick, as you have to work with the full path. but I don't understand why there was no exception when the files could not be found...
EDIT to put the change to a more prominent place:
You as well seem to have your path wrong.
Use
folder = r"C:\Documents and Settings\DuffA\Bureaublad\test"
to prevent that the \t is turned into a tab character.

for root, dirs, filenames in os.walk(folder):
for filename in filenames:
os.rename(os.path.join(root,filename),
os.path.join(root,'%s_manual%s' % os.path.splitext(filename)))
you should add a control in your code, to verify that the filename to rename hasn't already '_manual' in its string name

Related

How do I move files within a subfolder in a directory to another directory in python?

import os
import shutil
source_dir = r'C:\\Users\\Andre\\Downloads'
image_dir = r'C:\\Users\\Andre\\Downloads\\images'
file_names = os.listdir(source_dir)
for file_name in file_names:
if '.png' in file_name:
shutil.move(os.path.join(source_dir, file_name), image_dir)
This current code will move all pngs from source dir to image dir, how can I make it so it also includes pngs nested in another subdirectory inside the source dir? for example C:\Users\Andre\Downloads\pictures
You can break the moving functionality into a function, then call that function on each directory.
def move_pngs(src, dst):
for file_name in os.listdir(src):
if file_name.endswith('.png'):
shutil.move(os.path.join(src, file_name), dst)
move_pngs(source_dir, image_dir)
move_pngs(os.path.join(source_dir, 'pictures'), image_dir)
... Or maybe go full recursive.
def move_pngs(src, dst):
for file_name in os.listdir(src):
fullname = os.path.join(src, file_name)
if os.path.isdir(fullname) and fullname != dst:
move_pngs(fullname, dst)
elif file_name.endswith('.png'):
shutil.move(fullname), dst)
This will visit all subdirectories recursively, and move all files into one flat directory, meaning if there are files with the same names anywhere, generally the one from a deeper subdirectory will win, and the others will be overwritten.
You can simply just change the source_dir to also include the subdirectory which you want to move the pngs from and run then the loop again.
In this case:
subdirectory = '\pictures'
source_dir += subdirectory
file_names = os.listdir(source_dir)
for file_name in file_names:
if '.png' in file_name:
shutil.move(os.path.join(source_dir, file_name), image_dir)

i have an exported file that comes out with spaces, and i want to change that file to have hyphens

My current code is:
import os
path = os.getcwd()
filenames = os.listdir("C:/Users/Larso/Desktop/ClearEstimatesEstimate/")
filename = ('Leap Price Guide Export.xlsx')
for filename in filenames:
os.rename(os.path.join(path, filename), os.path.join(path, filename.replace(' ', '-')))
for filename in filenames:
os.rename(filename, filename.replace(" ", "-"))
but i get error
FileNotFoundError: [WinError 2] The system cannot find the file specified: 'C:\\Users\\larso\\Desktop\\ClearEstimatesEstimate\\AutomateExcelfileintoaspecficExcelfileformat\\AutomateExcelfileintoaspecficExcelfileformat' -> 'C:\\Users\\larso\\Desktop\\ClearEstimatesEstimate\\AutomateExcelfileintoaspecficExcelfileformat\\AutomateExcelfileintoaspecficExcelfileformat'
any thoughts how to automate that
Just a wild guess:
Has your path variable
path = os.getcwd()
the same path as your filenames path
filenames = os.listdir("C:/Users/Larso/Desktop/ClearEstimatesEstimate/")
Because you combine the path from the path variable with the filename from an filenames variable.
os.path.join(path, filename)
Please print both path values and compare them for differences. Or better use your path variable in your filenames variable:
filenames = os.listdir(path)
os.getcwd() is going to give you the path from which you're running the script.
os.listdir(path) is going to give you the list of filenames in the directory at path.
So the absolute path of the file in your working directory will be:
os.getcwd() + '/' + filename
Try this, with your script in the same directory as your files you want to rename.
import os
path = os.getcwd()
filenames = os.listdir(path)
for filename in filenames:
current_filename = path + '/' + filename
os.rename(current_filename, current_filename.replace('_', ' '))

Why does this Python (using 3.7) renamer not allow directories to start with a number?

I have created the following renamer (below) to replace periods from the filename and directory name, which seems to work fine for filenames but doesn't work for directory names if they start with an integer. No errors are raised. If there are no integers in any directory names, then it works fine for directories. Otherwise, it simply renames the files but not the directories. Can anybody tell me why and how to get around this?
Any help is much appreciated.
import os
def Replace_Filename(Root_Folder):
for Root, Dirs, Files in os.walk(Root_Folder):
for File in Files:
print(File)
Fname, Fext = os.path.splitext(File)
print(Fname)
print(Fext)
Replaced = Fname.replace(".","_")
print(Replaced)
New_Fname = Replaced + Fext
print(New_Fname)
F_path = os.path.join(Root, File)
print(F_path)
New_Fpath = os.path.join(Root, New_Fname)
print(New_Fpath)
os.rename(F_path, New_Fpath)
def Replace_Dirname(Root_Folder):
for Root, Dirs, Files in os.walk(Root_Folder):
for Dir in Dirs:
print(Dir)
New_Dname = Dir.replace(".","_")
print(New_Dname)
D_Path = os.path.join(Root, Dir)
print(D_Path)
New_Dpath = os.path.join(Root, New_Dname)
print(New_Dpath)
os.rename(D_Path, New_Dpath)
Root_Folder = "D:\\Practicerename-Copy"
Replace_Filename(Root_Folder)
Replace_Dirname(Root_Folder)

Loop over files in subdir and put output in other subdir

I want to perform an action on all files in a subdir and put the out put in another dir. For example, in /Pictures/ there are subdirs /January, /February/ etc and in them imgages. I want to perform actions on the images and put the output to /Processed/ and its subdirs /January, /Februady etc.
I imagine it to be solved something like this, but I really could use some help:
import os
path = '/Pictures/'
outpath = '/Processed/'
for subdir, dirs, files in os.walk(path):
#do something with files and send out put to corresponding output dir
This should give you the basic structure :
import os
path = 'Pictures/' # NOTE: Without starting '/' !
outpath = 'Processed/'
for old_dir, _, filenames in os.walk(path):
new_dir = old_dir.replace(path, outpath, 1)
if not os.path.exists(new_dir):
print "Creating %s" % new_dir
os.makedirs(new_dir)
for filename in filenames:
old_path = os.path.join(old_dir, filename)
new_path = os.path.join(new_dir, filename)
print "Processing : %s -> %s" % (old_path, new_path)
# do something with new_path
It creates the same subfolder structure in 'Processed/' as in 'Pictures/' and it iterates over every filename.
For every file in your folders, you get the new_path variable :
old_path is 'Pictures/1/test.jpg', new_path will be 'Processed/1/test.jpg'
This basically walks through all folders of a directory, gets its files; perform some action with performFunction() and write to the same file. You can modify this to write to different path!
def walkDirectory(directory, filePattern):
for path, dirs, files in os.walk(os.path.abspath(directory),followlinks=True):
for filename in fnmatch.filter(files, filePattern):
try:
filepath = os.path.join(path, filename)
with open(filepath) as f:
s = f.read()
s = performFunction()
with open(filepath, "w") as f:
print filepath
f.write(s)
f.flush()
f.close()
except:
import traceback
print traceback.format_exc()
Hope it helps!

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