I’m currently working on a website project for the Finxter ecosystem, where I’m given a folder with subfolders (and subfolders within) that contain image files.
Example folder structure:
folder -- subfolder1 ---- image1.jpg ---- image2.jpg ---- image3.jpg -- subfolder2 ----image1.jpg ----image2.jpg
Across the subfolders, the files may have the same name, which causes an issue when uploading all files to my webserver. To fix all issues, I want to rename all files, so they have unique names.
💡 Project Goal: My simple idea was to add a prefix with the folder structure in front of each file name. For example, a file named
'myfile1.jpg' in folder
'myfolder1' will be renamed to the new file
'myfolder1_myfile1.jpg'. All the files with new names should be copied into a subfolder as specified in a
Desired output folder structure:
destination ---- subfolder1_image1.jpg ---- subfolder1_image2.jpg ---- subfolder1_image3.jpg ---- subfolder2_image1.jpg ---- subfolder2_image2.jpg
Here’s the code to accomplish this — I’ll explain it in a minute! 👇
# import os and sys modules import os, sys import shutil # get the root directory from command line argument root_dir = '.' destination = './my_destination' # walk through the directory tree for dirname, subdirs, files in os.walk(root_dir): # for each directory, print the directory's path print(dirname) # for each file in the directory, copy and rename for file in files: new_name = dirname[2:].replace('\\', '_') + "_" + file shutil.copy(os.path.join(dirname, file), os.path.join(destination, new_name))
You need to give absolute or relative paths from the perspective of this Python file. It’ll already run fine if the Python file is stored in the same folder as the subfolders. But you need to have a subfolder called
How does this code work?
This code recursively copies all files in a directory tree to a specified destination folder.
You take the root and destination directories and iterate through each directory and subdirectory within the root directory. For each directory, you print out the directory’s path.
For each file in the directory, you copy it to the specified destination folder, renaming it to include the path of the original directory in the name.
I used string slicing and the
string.replace() method to modify the destination filenames according to my goals, see the following line:
new_name = dirname[2:].replace('\\', '_') + "_" + file
Note that the double backslash
\\ is actually an (escaped) single backslash character that you usually don’t want in your new filename. We replace all of this with single underscores such that a file
While working as a researcher in distributed systems, Dr. Christian Mayer found his love for teaching computer science students.
To help students reach higher levels of Python success, he founded the programming education website Finxter.com that has taught exponential skills to millions of coders worldwide. He’s the author of the best-selling programming books Python One-Liners (NoStarch 2020), The Art of Clean Code (NoStarch 2022), and The Book of Dash (NoStarch 2022). Chris also coauthored the Coffee Break Python series of self-published books. He’s a computer science enthusiast, freelancer, and owner of one of the top 10 largest Python blogs worldwide.
His passions are writing, reading, and coding. But his greatest passion is to serve aspiring coders through Finxter and help them to boost their skills. You can join his free email academy here.