Friday, July 5, 2013

Python read file dates and rename files with datestamps

A piece of code that's so small that does so many things. Searches a directory for all files matching a pattern, gets the modification date of each file, and adds that plus a label to the file name. Uses glob to handle the searching, gets a list of matching files (may be empty if no matches, uses getmtime to get the mod time and formats it with time.strftime, uses split to dice up the original file name, and replace to slap on the label and time stamp and rejoin the new file name to the original path.

def RenameFiles(Directory, Label):

SearchString = Directory + '/pattern*'
tekfiles = glob.glob(SearchString)
for f in tekfiles:
create_date = time.strftime("%Y%m%d_%H%M%S",time.localtime(os.path.getmtime(f)))
pieces = f.split('\\')
new_name = pieces[0] + '/' + pieces[1].replace('tek','%s_pattern' % Label).replace('.','_%s.' % create_date)
os.rename(f,new_name)

Some links:

Shows use of os.rename, glob, and picking out pieces of a filename with array indexes (which I didn't use in the final code):
http://stackoverflow.com/questions/2759067/rename-files-in-python

Shows use of getctime and getmtime. It turns out that since my directory is full of copied files, that getmtime is more useful because the ctime of the copied file reflects its copy date (and can thus be later than the mtime):
http://stackoverflow.com/questions/10149994/with-python-how-to-read-the-date-created-of-a-file
http://stackoverflow.com/questions/237079/how-to-get-file-creation-modification-date-times-in-python

It took a bit of work to figure out how to take the result of getmtime and format it into a string. The result in unix epoch seconds had to be converted to a time tuple using time.localtime so that it could be formatted using time.strftime. Some of that is shown in the previous links but I also read these doc pages:
http://docs.python.org/2/library/time.html
http://epydoc.sourceforge.net/stdlib/time-module.html

Shows use of glob. I was originally thinking of making a full-featured search like my own version of 'find', but it turned out that I only needed to search specific directories, so glob did everything I really needed:
http://code.activestate.com/recipes/499305-locating-files-throughout-a-directory-tree/
http://docs.python.org/2/library/glob.html

The link which gave me the genius suggestion of using nested replace() calls to do the two filename modifications simultaneously:
http://stackoverflow.com/questions/8687018/python-string-replace-two-things-at-once