DEV Community

josephmads
josephmads

Posted on • Updated on

(Another) Simple Python File Renaming Script

Intro

This is a walk-through of a file renaming script that allows the user to specify the type of file to be renamed and to choose the naming convention.

The Script

import pathlib

# set the directory containing the files to be renamed
path = pathlib.Path("/home/joe/Pictures/examplePics/")

# set the new name of the files 
file_name = "photos"
file_list = []
counter = 1

for file in sorted(path.glob("*.JPG")): # file type to rename
    file_list.append(file)
for file in file_list:
    new_file = file_name + str(counter) + str(file.suffix).lower()
    file.rename(path / new_file)
    counter += 1
Enter fullscreen mode Exit fullscreen mode

How It Works

This directory has two file types, .jpg and .txt. For this example I only want to change the names of the .jpg files.

directory of files to change

First, the script imports the pathlib module from the standard library. Functions from this module allow the script to navigate directories, iterate by file type, and rename files. The .Path() class tells the script where the files are that need to be renamed. It gets assigned to the path variable.

import pathlib

path = pathlib.Path("/home/joe/Pictures/examplePics/")
Enter fullscreen mode Exit fullscreen mode

If the script is run from the same directory as the files being renamed, path can be written:

path = pathlib.Path().cwd()
Enter fullscreen mode Exit fullscreen mode

Next, the user assigns a string to file_name which will become the stem of the new file names. file_list initializes an empty list. counter starts the file numbering scheme at 1.

file_name = "photo"
file_list = []
counter = 1
Enter fullscreen mode Exit fullscreen mode

The first 'for loop' iterates over the files that path points to. The .glob() method specifies the file type by matching the relative pattern (also assigned by the user). The files are sorted and appended to the file_list that was initialized above.

for file in sorted(path.glob("*.JPG")): # file type to rename
    file_list.append(file)
Enter fullscreen mode Exit fullscreen mode

Without this first 'for loop', there is a fringe case where the renaming script overwrites and erases some files. This happens if it is run twice in a row without changing the file_name string. I only encountered this problem in Linux (both WSL and a Linux machine) when running the script from outside the working directory. I could not get Windows to duplicate the problem.

It doesn't seem very likely that the user would run into this file erasure issue. However, since no one likes unexpectedly losing files, I kept it in the script just to be on the safe side.

The second 'for loop' iterates over the sorted files appended to file_list. new_file is initialized and the new file name is concatenated from the string in file_name, the integer in counter (converted to a string), and the file type suffix specified in the first 'for loop'. file.suffix is converted to a string and made lowercase using the .lower() string method.*

for file in file_list:
    new_file = file_name + str(counter) + str(file.suffix).lower()
Enter fullscreen mode Exit fullscreen mode

*I made the file suffix conversion because I like my file extensions lowercase. If uppercase extensions are preferred, or the extensions are already lowercase, the line can be written like this:

    new_file = file_name + str(counter) + file.suffix
Enter fullscreen mode Exit fullscreen mode

Finally, the .rename() method renames the file to the targeted directory path and returns a new Path instance pointing to target.
counter is increased by 1, and the script loops until every specified file has been renamed.

    file.rename(path / new_file)
    counter += 1
Enter fullscreen mode Exit fullscreen mode

After the script is run the directory looks like this:

directory of changed files

Thanks for reading!


Edited 4/25/2022

DISCLAIMER:
I wrote this script and this article as part of an assignment for my programming course. While I believe this script to be safe, I am a beginner and this script should be treated as an imperfect tool. If you choose to use this script, please test it on a sample or practice directory first.

Discussion (8)

Collapse
josephmads profile image
josephmads Author

Never use any code you don't fully understand.

That is a good point to keep in mind. Thanks!

I did try to address the file deleting problem in my script. By adding the for loop that first appends all of the file names to a sorted list, I was able to keep the files from being erased if the script is run twice in a row. I tested this to the best of my ability and was not able to make the script erase the files with this for loop in place. Were you able to get different results testing it?

I'm still a newbie to Python. I'm about 5 weeks into learning program so I'll be the first to tell you how much I don't know. :-)

Collapse
xarop_pa_toss profile image
Ricardo Giro

Very interesting read! I'm stealing this for personal use if you don't mind :P My camera still names photos something like IMG_02020324 so being able to just rename hundreds of photos in a few seconds is amazing. Damn programming is cool as heck

Collapse
josephmads profile image
josephmads Author

Please do! Let me know if you come across any issues or ways to improve the script. I'm about a month into my Python learning journey and I appreciate all feedback.

I agree, programming rules!

Collapse
josephmads profile image
josephmads Author

Thanks, I will check those tricks out. I'm always appreciative of feedback!

Collapse
code_with_ali profile image
AlixaProDev

Informative. Thanks for the share.

Collapse
josephmads profile image
josephmads Author

You're welcome, and thank you for reading!