Batch rename files using a CSV in Python
Use this simple Python script to change hundreds or thousands of file names automatically, based on a CSV. This procedure will work on all operating systems.
You may be faced with a situation where you need to change the names of many files across multiple directories. Changing file names manually is cumbersome and impractical. The following is a method that I use in Python that will take a simple CSV file containing a list of file names and change them all according to the list. It’s quick and reliable.
I have previously written about a PowerShell method for achieving this, but I prefer Python because it works across all operating systems.
There are several parts to this procedure:
The CSV file
The first step to this procedure is to generate a CSV (comma-separated values) file that contains two columns:
- “filepath”: This column contains the full path to each file that needs to have its name changed.
- “filename”: This column contains the new name for the file.
The CSV file would need to be populated as follows:
filepath,filename
c:\path\to\filename1.JPG,newfilename1.JPG
c:\path\to\filename2.JPG,newfilename2.JPG
etc
Whilst you could generate the list of existing files (in the first column) manually, I recommend that you automate this procedure.
When your file has been created, save it as “rename.csv” in the target directory.
The Code
The below code is written in Python and will read the contents of the “rename.csv” file, changing the names of any valid files that it can identify in the first column to the new name specified in the second column.
I have named this script file csvrename.py.
#!/usr/bin/env python
import os
import csv
import glob
import sys
import argparse
from datetime import datetime
from csv import reader
# Intro Text
print("\033[1;34;40m\n\nRename files from a CSV \033[0m")
print("\033[1;36;40mWritten by Adam M. Dimech\n \n \n \033[0m")
def options():
parser = argparse.ArgumentParser(description="Create a list of images from a folder in a CSV file")
parser.add_argument("-f", "--folder", help="Target folder of images.", required=True)
args = parser.parse_args()
return args
def main():
# Get options
args = options()
# Identify the target directory
target_raw = args.folder # r required to prevent reformatting numbers in path
if sys.platform.startswith('win'):
target_raw = target_raw.replace('\\', '/')
if not target_raw.endswith('/'):
target = target_raw+"/"
else:
target = os.path.join(target_raw, '')
else:
target = os.path.join(target_raw, '') # Add trailing slash if missing
# Check if renaming file exists
number_renames = len(glob.glob(target + '*renam*.csv'))
if number_renames == 0:
print("There is no 'renaming' CSV file in directory ", target, ". Please create one to continue.\n")
raise SystemExit
if number_renames >1:
print("Oops! There are", number_renames, "'renaming' CSV files in", target, ". Ensure there is only one 'renaming' file in directory.\n")
raise SystemExit
elif number_renames ==1:
csv_file = glob.glob(target + '*renam*.csv')
csv_file = csv_file [-1] # Convert from list to variable
if sys.platform.startswith('win'):
if csv_file.endswith('/'):
csv_file_rename = csv_file[:-1]
csv_file_rename = csv_file.replace('\\', '/')
print("Your renaming CSV file is located at: "+csv_file_rename+"\nPreparing to rename images...")
# Rename the CSV - Open file in read mode
with open(csv_file_rename, 'r') as read_obj:
csv_reader = reader(read_obj) # pass the file object to reader() to get the reader object
index = 0
for row in csv_reader: # Iterate over each row in the csv using reader object
index += 1 #Apply index to return row number in CSV
now = datetime.now()
if not row[1] == '': # Check that there's a proposed rename
if not index == 1: # Check that a header row isn't being used for conversions.
src = row[0]
dst = row[1]
if os.path.dirname(dst) == '': # Check that a full path is offered and if not, add one.
filename, file_extension = os.path.splitext(src) # Get src file extension
folderpath = os.path.dirname(src) # Add folder path if not specified
dst = os.path.splitext(dst)[0] # Remove file extension if present
dst = folderpath+"/"+dst+file_extension
if not os.path.isfile(src) is True: # Check that the source file can be found.
print("\033[1;31;40mWarning:\033[0m Cannot locate "+src+" (Row:"+str(index)+").")
elif os.path.isfile(dst) is True: # Check that the renamed file doesn't already exist.
print("\033[1;31;40mWarning:\033[0m File "+src+" has already been created.")
else: # Rename the file
os.rename(src, dst)
dst_short = os.path.basename(dst)
print("\033[1;32;40mSuccess!\033[0m File "+src+" (Row:"+str(index)+") was successfully renamed '"+dst_short+"' at "+now.strftime("%d-%m-%Y %H:%M:%S:%f"))
else:
print("\033[1;36;40mWarning:\033[0m File "+row[0]+" (Row:"+str(index)+") does not have a rename specified in the CSV file.")
print("Job complete.")
if __name__ == '__main__':
main()
Here’s how it works:
- The code looks for a CSV file containing the string “renam” in the target directory, so that it can automatically identify the CSV that contains the renaming instructions. If there are multiple files that meet this criterion, you will be warned and required to change the names of the erroneous offending files.
- The CSV is opened and each row is read. The code checks that each file can be found.
- If the file can be found, the file name will be changed to whatever is specified in the second column of the CSV.
- The results of this renaming process will be printed to the screen.
Files that are not included in the CSV will be ignored.
The Command
To execute this command, you will need to activate your Python environment and then enter two variables on the command line:
- The full path to csvrename.py
-f
: The directory that you want to search to locate the rename.csv file (required)
So, a search of c:\users\myname\Downloads
would be entered as follows:
c:\path\to\csvrename.py -f c:\users\myname\Downloads
Provided that c:\users\myname\Downloads\rename.csv
can be found and is correctly formatted and populated, the file names will be changed.
Important note: There is no “undo” operation with this procedure. Proceed with caution.
Download the Code
You can download the code on GitHub Gist.
Comments
No comments have yet been submitted. Be the first!