Zia Ranks Zia Ranks - 1 month ago 9
Python Question

batch rename files by common unique value

I have a folder containing over 500 images. and a text file with new names for these images. I have tried to create a renaming script in python but I am struggling with the robustness issue. I would like to rename the file by selecting the new name by unique identifier

I wrote this...

import os
import csv


img_dir = str(raw_input("Path to Images Folder as C:/path/to/IMAGES : "))
os.chdir(img_dir)

newNames_file = str(raw_input("csv file path and name as C:/path/to/loc_data.csv : "))

with open(newNames_file, 'rb') as f:
reader = csv.reader(f)
newNames = list(reader)


newNames = [l[0] for l in newNames]

print"Current Working Directory is: " + os.getcwd()

path = os.getcwd()
filenames = [os.path.join(img_dir,fn) for fn in next(os.walk(img_dir))[2]]

assert len(filenames) == len(newNames)

for i in range(len(newNames)):
os.rename(str(filenames[i]), str(newNames[i]))


but the results are unreliable.. e.g. the order inst guaranteed to match.

How can I use the unique ID to pass the correct value top the rename function?

the file names are raw e.g.
IMG_3036.tif


and the new values are in the form
7700_50fpl_4_1_3036


where 3036 is the unique ID

Answer

I write a script and i think it will do the trick.

You can rewrite the get_name_uid function to get your new files' uid and old files's uid if you want.

Make sure you change the glob name and new_names file name as you use.

import glob
import os

old_image_filenames = glob.glob('*.img')
new_names = open('new_names').read().strip().split(',')

def get_name_uid(name):
    uid = name.split('.')[0]
    uid = uid.split('_')[-1]

    return uid


def get_uid_filename_map(filenames, get_uid_func):
    uid_filename_map = {}
    for filename in filenames:
        uid_filename_map[get_uid_func(filename)] = filename

    return uid_filename_map

uid_old_filenames = get_uid_filename_map(old_image_filenames, get_name_uid)
uid_new_filenames = get_uid_filename_map(new_names, get_name_uid)

for uid in uid_old_filenames.keys():
    if uid in uid_new_filenames:
        os.rename(uid_old_filenames[uid], uid_new_filenames[uid])

The folder i run script before

$ ls 
new_names       play.py         zasdf_3036.img  zxcsdf_3037.img

after run script

$ ls
7700_50fpl_4_1_3036.img 7700_50fpl_4_2_3037.img new_names               play.py

file new_names

$ cat new_names
7700_50fpl_4_1_3036.img,7700_50fpl_4_2_3037.img