Wednesday, December 28, 2011

a piece of py: renaming files

I hate spaces in the names of files. It's a quirk of my personality. I prefer CamelCase as an alternative. I used to like a mix of lower case letters, hyphens and underscores, but that was before my world of Unix and Python was dominated by Java.

However, I am a member of the minority and so I often end up with folders and files whose names aspire to be sentences (or at least parts of speech like nouns, prepositions, pronouns and the occasional verb [To be DELETED: ugh!). Today was one of those days. I had a folder full of PDFs, each with a name of the form Last, First.pdf. I would have preferred a name like FirstLast.pdf. The easiest way to do this was with some shell-fu or Python-fu (with due apologies to the GIMP). I tossed a coin and chose Python. I fired up PythonWin and started working on fragments that would eventually unite into a single one-liner to rename them all (sorry JRR). I wasn't smart enough to reduce it all to one line (I needed the imports and I was not a lambda knight).

import fnmatch, os
# basedir is a string representing the full path to the folder
# containing the poor PDFs
for pdf in fnmatch.filter(os.listdir(basedir), '*.pdf'):
  new_name = ".".join(["".join(reversed(pdf.split('.')[0].split(', '))), 
                      pdf.split('.')[1]])
  os.rename(os.path.join(basedir, pdf), os.path.join(basedir, new_name))

Of cours,e I could have skipped using new_name completely:

import fnmatch, os
# basedir is a string representing the full path to the folder
# containing the poor PDFs
for pdf in fnmatch.filter(os.listdir(basedir), '*.pdf'):
  os.rename(os.path.join(basedir, pdf), 
         os.path.join(basedir, 
                 ".".join(["".join(reversed(pdf.split('.')[0].split(', '))), 
                 pdf.split('.')[1]])))

I think this might be the first time I used reversed(), but since it was a relatively recent addition (2.4 to be precise), I didn't feel too bad. Had I written this code before 2.4 had been released, I would have been forced to use reverse(): this also reversed the list, but did it in place and did not return the list; I would be forced to reverse the list first and then send it onto the join conveyor belt.

I also like how just adding brackets as bookends to items separated by commas, I get a list:

["".join(reversed(pdf.split('.')[0].split(', '))), pdf.split('.')[1]]

Mission accomplished. With some learning to boot. Not bad for a few minutes of work.

No comments:

 
Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.