Increment single file

Viewed 68

Newbie here. There are many ways to rename files in your folder, however, does anyone know how to rename just a single file incrementally? for example in a folder I have image.jpg, and each time I run the code, it will rename image.jpg in the folder and increment to newimage1.jpg and if the folder contains newimage1 after running the code again, it will rename that file to newimage2.jpg so on and so forth.

import os
os.chdir('C:\\Users\\Desktop\\Folder1')
i=0
for file in os.listdir():
    src=file
    if src=='image.jpg':
            #How do i make use of counter to increment the image name each time i run this code?
            dst="newimage.jpg"
            os.rename(src,dst)  

The code above renames a single file once.

2 Answers

Just check for the existence of the file and increment the counter if need be:

from pathlib import Path
src = Path("/path/to/image.jpg")
i = 0
dst = src.with_name(f"new-{src.stem}_{i:03}.{src.suffix}")

# or if using python >=3.9:
# dst = src.with_stem(f"new-{src.stem}_{i:03}")

while dst.exists():
    i += 1
    dst = src.with_name(f"new-{src.stem}_{i:03}.{src.suffix}")
    # or as before

src.rename(dst)

Note that with python>=3.9 you can use with_stem in place of the ugly reimplementation using with_name, throughout. I'm surprised it took so long to add it; I gave up waiting for such an obvious method. Thanks to @OlvinRoght for pointing that out.

The {i:03} zero-pads the counter, which you probably want, to make sure '2' always sorts before '11'.

EDIT: @buran points out that this is not safe if anything else could modify the output directory, because the file might not exist when we test (dst.exists()) but be created by time we get to src.rename(dst). If you know that nobody else can touch the directory, you can do it as above, but the safer way is to try the move and bail if the file exists:

i = 0
while True:
    dst = src.with_name(f"new-{src.stem}_{i:03}.{src.suffix}")
    try:
        dst.rename(src)
        break
    except FileExistsError:
        i += 1

This is safer because the error is thrown by the underlying OS at the rename moment, so we delegate avoiding race conditions to the OS's mv or rename utility (or syscall), hoping that this operation is atomic (which it should be).

..and each time I run the code, it will rename image.jpg in the folder and increment to newimage1.jpg and if the folder contains newimage1 after running the code again, it will rename that file to newimage2.jpg so on and so forth.

Something like the below

import os

os.chdir('C:\\Users\\Desktop\\Folder1')
for file in os.listdir():
    if file=='image.jpg':
        dst ="newimage_0.jpg"
        os.rename(file,dst)  
        break
    elif file.startswith('newimage_'):
      idx = int(file[file.find('_')+1: file.find('.')])
      os.rename(file,f'newimage_{idx}.jpg')
      break
Related