Skip to content

Dear Internet Explorer user: Your browser is no longer supported

Please switch to a modern browser such as Microsoft Edge, Mozilla Firefox or Google Chrome to view this website's content.

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:

The CSV file would need to be populated as follows:


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

#!/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+"/"
			target = os.path.join(target_raw, '')
		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 =
			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"))
				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__':

Here’s how it works:

  1. 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.
  2. The CSV is opened and each row is read. The code checks that each file can be found.
  3. If the file can be found, the file name will be changed to whatever is specified in the second column of the CSV.
  4. 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:

So, a search of c:\users\myname\Downloads would be entered as follows:

c:\path\to\ -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.



No comments have yet been submitted. Be the first!

Have Your Say

The following HTML is permitted:
<a href="" title=""> <b> <blockquote cite=""> <code> <em> <i> <q cite=""> <strike> <strong>

Comments will be published subject to the Editorial Policy.