Recursively rename file extensions - python

I am having a difficult time creating a python script that will rename file extensions in a folder and continue to do so in sub directories. Here is the script I have thus far; it can only rename files in the top directory:
#!/usr/bin/python
# Usage: python rename_file_extensions.py
import os
import sys
for filename in os.listdir ("C:\\Users\\username\\Desktop\\test\\"): # parse through file list in the folder "test"
if filename.find(".jpg") > 0: # if an .jpg is found
newfilename = filename.replace(".jpg","jpeg") # convert .jpg to jpeg
os.rename(filename, newfilename) # rename the file

import os
import sys
directory = os.path.dirname(os.path.realpath(sys.argv[0])) #get the directory of your script
for subdir, dirs, files in os.walk(directory):
for filename in files:
if filename.find('.jpg') > 0:
subdirectoryPath = os.path.relpath(subdir, directory) #get the path to your subdirectory
filePath = os.path.join(subdirectoryPath, filename) #get the path to your file
newFilePath = filePath.replace(".jpg",".jpeg") #create the new name
os.rename(filePath, newFilePath) #rename your file
I modified Jaron's answer with the path to the file and the complete example of renaming the file

I modified the answer of Hector Rodriguez Jr. a little bit because it would replace ANY occurance of ".jpg" in the path, e.g. /path/to/my.jpg.files/001.jpg would become /path/to/my.jpeg.files/001.jpeg, which is not what you wanted, right?
Although it is generally not a good idea to use dots "." in a folder name, it can happen...
import os
import sys
directory = os.path.dirname(os.path.realpath(sys.argv[0])) # directory of your script
for subdir, dirs, files in os.walk(directory):
for filename in files:
if filename.find('.jpg') > 0:
newFilename = filename.replace(".jpg", ".jpeg") # replace only in filename
subdirectoryPath = os.path.relpath(subdir, directory) # path to subdirectory
filePath = os.path.join(subdirectoryPath, filename) # path to file
newFilePath = os.path.join(subdirectoryPath, newFilename) # new path
os.rename(filePath, newFilePath) # rename

You can process the directory like this:
import os
def process_directory(root):
for item in os.listdir(root):
if os.path.isdir(item):
print("is directory", item)
process_directory(item)
else:
print(item)
#Do stuff
process_directory(os.getcwd())
Although, this isn't really necessary. Simply use os.walk which will iterate through all toplevel and further directories / files

Do it like this:
for subdir, dirs, files in os.walk(root):
for f in files:
if f.find('.jpg') > 0:
#The rest of your stuff
That should do exactly what you want.

Related

open a folder to then use the files in python correctly

Usually I navigate to the folder I am extracting data from and copy the file name directly:
df2=pd.read_csv('10_90_bnOH-MEA.csv',usecols=[1])
If I have multiple files and want to do the same for all the files, how do I specify the folder to open and get all the files inside?
I want to run the above code without specifying the file's full path
(C:\Users\X\Desktop\Y\Z\10_90_bnOH-MEA.csv)
You want listdir from the os module.
import os
path = "C:\\Users\\X\\Desktop\\Y\\Z\\"
files = os.listdir(path)
print(files)
dataframe_list = []
for filename in files:
dataframe_list.append(pd.read_csv(os.path.join(path,filename)))
You should open the desired directory and loop through all the files then do something to them.
# import required module
import os
# assign directory
directory = 'files'
# iterate over files in
def goThroughDirectory(directory):
for filename in os.listdir(directory):
f = os.path.join(directory, filename)
# checking if it is a file
if os.path.isfile(f):
# do something
If you also want to loop through all the files in a directory you should add a check for if os.path.isdir(f) like this
...
def goThroughDirectory(directory):
for filename in os.listdir(directory):
f = os.path.join(directory, filename)
# checking if it is a file
if os.path.isfile(f):
# do something
elif os.path.isdir(f):
# its not a file but a directory then loop through that directory aswell
goThroughDirectory(directory + "\" + f)
for more information you should check geeksforgeeks

How to copy specific files from the sub-folders to a new folder in python?

I have a folder with several sub-folders, each containing the same number of files (here it is 7). The code that I use at the present copies all the files from the different sub-folders within a main folder, to another new folder.
import os
import shutil
src = r'C:\Users\datasets\test\0'
dest = r'C:\Users\datasets\data_new\test\0'
for path, subdirs, files in os.walk(src):
for name in files:
filename = os.path.join(path, name)
shutil.copy2(filename, dest)
I need to modify the code in a way to copy only the last image (i.e. the 7th image in this case) from each sub-folder (windows file arrangement) to a new folder.
This should do it for you.
import os
import shutil
from glob import glob
src = r'C:\temp\datasets\test\0'
dest = r'C:\temp\datasets\data_new\test\0'
for base, dirs, _ in os.walk(src):
for path in dirs:
files = sorted(glob(os.path.join(base, path, '*')))
if len(files) == 0:
continue
file = files[-1]
filename = os.path.join(path, file)
shutil.copyfile(filename, dest)

How to find 2 specific .py files and run them

I have 2 '.py' files in many sub-folders. And would like to run them one at a time.
First, I would like to run the first one in all sub-folders and then run the second. Also, lets say the first one is named AAA and the second is BBB.
Below is my script.
import os
import sys
rootdir = os.getcwd()
for subdir, dirs, files in os.walk(rootdir):
for file in files:
#print(os.path.join(subdir, file))
filepath = subdir + os.sep + file
if filepath.endswith("A*.py or B*"):
print(filepath)
os.startfile(filepath)
Try this:
if (filepath.endswith("A*.py" or "B*")):
os.startfile(filepath)
print(filepath)
The if filepath.endswith("A*.py or B*"): is the problem. The str.endswith doesn't work like this. This condition should work:
if file == "AAA.py" or file = "BBB.py":
Also start the file in the if block, so this is the full code:
import os
import sys
rootdir = os.getcwd()
for subdir, dirs, files in os.walk(rootdir):
for file in files:
#print(os.path.join(subdir, file))
filepath = subdir + os.sep + file
if file == "AAA.py" or file = "BBB.py":
print(filepath)
os.startfile(filepath)

renaming all images in folders using the name of the folder

I have a lot of folders. in each folder, there is an image. I want to rename all of the images with the name of its folder.
For example:
Folder "1" has an image "273.jpg" I want to change it into the "1.jpg" and save it in another directory.
This is what I have done so far:
import os
import pathlib
root = "Q:/1_Projekte/2980/"
for path, subdirs, files in os.walk(root):
for name in files:
print (pathlib.PurePath(path, name))
os.rename(os.path.join(path, name), os.path.join(path, os.path.basename(path)))
print(os.path.basename(path))
The problem is that it works just for the first folder, then it jumps out with the error:
this file is already available...
the tree of folders and the images are like this:
Q:/1_Projekte/2980/1/43425.jpg
Q:/1_Projekte/2980/2/43465.jpg
Q:/1_Projekte/2980/3/43483.jpg
Q:/1_Projekte/2980/4/43499.jpg
So there is just one file in each directory!
Probably you have some hidden files in those directories. Check it out. If those files are not jpg, you can use following code:
for path, subdirs, files in os.walk(root):
for name in files:
extension = name.split(".")[-1].lower()
if extension != "jpg":
continue
os.rename(os.path.join(path, name), os.path.join(path, os.path.basename(path) + "." + extension))
print(os.path.basename(path))
This code extracts the extension of the file and checks if it is equal to the jpg. If file extension is not jpg, so continue statement will run and next file will check. If file type is jpg, script renames it. Also this code adds original file extension to the new name. Previous code didn't handle that.
I hope this helpe you.
Maybe this might help...
import os
root = "Q:/1_Projekte/2980/"
subdirs = [x for x in os.listdir(root) if os.path.isdir(x)]
for dir_name in subdirs:
dir_path = root + dir_name + '/'
files = os.listdir(dir_path)
print(dir_name)
print(files)
for i in files:
counter = 1
extension = i.split('.')[-1]
new_name = dir_name + '.' + extension
while True:
try:
os.rename(dir_path + i, dir_path + new_name)
break
except:
# If the file exists...
new_name = dir_name + '({})'.format(counter) + '.' + extension
counter += 1
This code ensures that even if a file with the existing name happens to exist, it will be suffixed with a number in brackets.

Find files, copy to new directory python

I would like to:
Write a script that takes a single directory path as command line argument, and then walks all subdirectories of that path looking for files with the extension '.py', copying each one to a temporary directory in your file system (eg /tmp/pyfiles). Your script should check for the existence of the temporary directory, and remove it if it already exists; it should then create a new directory, before beginning to copy files.
I have this:
#!/usr/bin/env python
import os, sys
import shutil
#import module
rootdir = sys.argv[1]
#take input directory
if os.path.exists('tmp/pyfiles'):
shutil.rmtree('tmp/pyfiles')
if not os.path.exists('tmp/pyfiles'):
os.makedirs('tmp/pyfiles')
#check whether directory exists, if it exists remove and remake, if not make
for root, dirs, files in os.walk(rootdir):
for f in files:
if os.path.splitext(f)[1] in ['.py']:
shutil.copy2(f, tmp/pyfiles)
#find files ending with .py, copy them and place in tmp/pyfiles directory
I get this error:
Traceback (most recent call last):
File "seek.py", line 20, in <module>
shutil.copy2(f, tmp/pyfiles)
NameError: name 'tmp' is not defined
Could anyone help me out?:) Thx
Your code says shutil.copy2(f, tmp/pyfiles), I believe it meant to be
shutil.copy2(f, 'tmp/pyfiles').
When you use the
os.walk()
method you loose track of the file full path. What I would do is to analyze each directory using the
os.listdir()
method and then copying each file taking into account its absolute path. Something like this:
for root, dirs, files in os.walk(rootdir):
for dir in dirs:
for f in os.listdir(dir):
if os.path.splitext(f)[1] in ['.py']:
shutil.copy2(os.path.join(root, dir, f), "tmp/pyfiles")
I hope this helps, maybe there is a cleaner solution.
You have to check if the root directory exists and walk in to remove everything if not create a new one.
To copy from dir to yours you have to check for files in dir that filename ends with .py, then replace the dir path with root path and create a new file in root dir with the content of matching file.
If we found a directory in dir we should create a new one in the root directory.
After that just call the function recursively to copy all content of dir to the root directory
import os, sys
rootdir = sys.argv[1]
PATH = "/tmp/pyfiles/"
def check(path, _file):
global rootdir, PATH
for item in os.listdir(path):
newpath = os.path.join(path, item)
if os.path.isdir(newpath):
os.mkdir(os.path.join(PATH, newpath.replace(rootdir, '')))
check(newpath, _file)
else:
if item.endswith(_file):
source = open(newpath, 'r')
print os.path.join(path, newpath.replace(rootdir, ''))
output = open(os.path.join(PATH, newpath.replace(rootdir, '')), 'w')
output.write(source.read())
output.close()
source.close()
if __name__ == '__main__':
if os.path.isdir(PATH):
for root, dirs, files in os.walk(PATH, topdown=False):
for name in files:
os.remove(os.path.join(root, name))
for name in dirs:
os.rmdir(os.path.join(root, name))
os.rmdir(PATH)
os.mkdir(PATH)
check(rootdir, '.py')

Categories