Python Rename Multiple Files

Do you like this?

Summary:
This script shows you an example how to rename multiple files with a similar structure in Python.


Content:

Let's consider a list of screenshots or photos taken by your camera. Suppose they all are in this format "Screenshot-<Number>.jpg" or "Photo-<Number>.jpg". Now the problem is their numbers are too large and you want to reduce them all by the same amount. For example, you want to change from ['photo-17.jpg', 'photo-18.jpg', ...] to ['photo-1.jpg', 'photo-2.jpg', ...]. The following script helps you do just that.

Below are the steps it carries out:

  1. create a sub folder to save all the renamed files
  2. filter all the files with the desired extensions such as JPG or anything of your choice. You will need to change the variable image_extensions at the top to suit your needs.
  3. sort all the files, i.e. ['photo-17.jpg', 'photo-18.jpg', ...]
  4. copy each of the files to the sub folder and then rename it accordingly.
import os
import shutil
import re

# constants
image_extensions = ['JPG']
subtract_amount = 16
image_folder= "images"
# end - constants

def get_alphanum_key_func():
        convert = lambda text: int(text) if text.isdigit() else text 
        return lambda s: [convert(c) for c in re.split('([0-9]+)', s)]

def natural_sort(list):
    """
    Sort the list into natural alphanumeric order.
    """
    sort_key = get_alphanum_key_func()
    list.sort(key=sort_key)

def filterImageFiles(filenames):
        result = []
        for filename in filenames: # loop through all the files and folders
                if os.path.isfile(os.path.join(os.path.abspath("."), filename)): # check whether the current object is a file or not
                        filename_text, filename_ext= os.path.splitext(filename)
                        filename_ext= filename_ext[1:]
                        filename_ext = filename_ext.upper()
                        if filename_ext in image_extensions: # check whether the current object is a JPG file
                                result.append(filename)
        natural_sort(result)        
        return result

def copy_rename(old_image_arr, new_image_arr):
        join= lambda s: "".join([str(x) for x in s])
        src_dir= os.curdir
        dst_dir= os.path.join(os.curdir , image_folder)
        src_file = os.path.join(src_dir, join(old_image_arr))
        shutil.copy(src_file,dst_dir)
        
        dst_file = os.path.join(dst_dir, join(old_image_arr))
        new_dst_file_name = os.path.join(dst_dir, join(new_image_arr))
        os.rename(dst_file, new_dst_file_name)

def empty_folder(folder):
    for the_file in os.listdir(folder):
        file_path = os.path.join(folder, the_file)
        try:
            os.unlink(file_path)
        except Exception, e:
            print e

def rebuild_image_folder():
    image_folder_path= os.path.join(".",image_folder)
    if os.path.exists(image_folder_path):
        print "Clearing %s" % image_folder_path
        empty_folder(image_folder_path)
    else:
        print "Creating %s" % image_folder_path
        os.mkdir(image_folder_path)

def main_processing():
        rebuild_image_folder()
        dir_entities= os.listdir('.')
        images = filterImageFiles(dir_entities)
        for image in images:
                image_name_arr= get_alphanum_key_func()(image) # ['sshot-',1,'.jpg']
                reduce_element_f = lambda v: str(v-subtract_amount) if isinstance(v,int) else v
                reduce_arr_f = lambda arr: [reduce_element_f(v) for v in arr]
                print "processing image: %s -> new name: %s" % (image,"".join(reduce_arr_f(image_name_arr)))
                copy_rename(image_name_arr,reduce_arr_f(image_name_arr))


if __name__ == "__main__":
        main_processing()
        

 
comments powered by Disqus