AppleScript BatchRenameFiles

Today we received a USB fully of family photos we took just before Christmas. For some reason, seeing all the IMG_73898.jpg files on the disk made me think, I wish I could rename these. Of course, there are a million ways to rename files, but I also have been tinkering with AppleScript ever since I wrote a script with Automator to copy Amazon Affiliate URL’s without all the surrounding iframe stuff.

So I did a little digging and here are the resources I found:

Apple Script to Batch Rename Files

Raduner.ch had a nice little script to rename files. It is simple and clean, and I wish my blog supported his syntax highlighter because it’s beautiful.

Apple Script to format numbers with a leading Zero

However, I wanted to be able to sort the files correctly after they were named, so I needed numbers below 10 to lead with a 0. So 01, 02, otherwise files would sort

file-1.jpg
file-10.jpg
file-11.jpg 

instead of

file-1.jpg
file-2.jpg
file-3.jpg

file-9.jpg
file-10.jpg

So I found a script at MacosxAutomation.com, which included a clever script to add_leading_zeros() to a number.

Batch Rename Drag’N Drop Files

Last but not least, I wanted to be able to drag and drop a bunch of files on my script, because with the Mac it is not uncommon to find the files first then try to figure out what to do with them.  So I turned my script into an application, and here is the code I put together.

As of Jan, 4 2015 this runs on OSX Yosemite (10.10.1).  No guarantees on earlier versions.

If the code is run from the script editor, then the default action (at the top level happens). IF however you drag and drop files onto the application, then the

on open

event occurs.

<pre class="brush: applescript;"><br></br><br></br>(***************************************************************************************<br></br> Default Action if double clicked and run like an app<br></br>***************************************************************************************)<br></br><br></br><br></br>set text item delimiters to "."<br></br>tell application "Finder"<br></br> (*<br></br>          the choose file opens a dialog.  Need to research that.<br></br> *)<br></br> set all_files to every item of (choose file with prompt "Choose the Files you'd like to rename:" with multiple selections allowed) as list<br></br> display dialog "New File name:" default answer ""<br></br> set new_name to text returned of result<br></br> repeat with index from 1 to the count of all_files<br></br>  set this_file to item index of all_files<br></br>  (*<br></br>   Because we changed the text item delimiter to ".", we will get a LIST from <br></br>   the file name itself, it will be split at the period.  So all file names<br></br>   will generally have 2 items (but may have more).<br></br>   If we just got the name of the file, we would get one text string, <br></br>   however because we also want the text items of that string, it will be split.<br></br>   This makes applescript weird.  Normally a split is EXPLICIT.  Here, it is implied/<br></br>   inferred by the language.  While it makes sense, it is also a level obscure.<br></br>   I.e., string.split(".") - you know is a funciton that will return a string converted<br></br>   into a list of strings.<br></br>   However, if I say, give me the text items of string<br></br>   you might think, but there is only one string, I have not broken it up yet.<br></br>   AppleScript says, no, when I ask for that, it is implied that you _will_ break<br></br>   it up.  You have to, in order to satisfy my request.<br></br>  *)<br></br>  set file_name_parts to text items of (get name of this_file)<br></br>  if number of file_name_parts is 1 then<br></br>   set file_extension to ""<br></br>  else<br></br>   set file_extension to "." & last item of file_name_parts -- note they used item -1<br></br>  end if<br></br>  (*<br></br>   To call a local script inside a tell you must use the **my** keyword.<br></br>   otherwise, the event is sent to finder / the application being "told"<br></br>  *)<br></br>  set indexStr to "-" & my add_leading_zero(index)<br></br>  -- used for debugging <br></br>  -- displayName("New name is: " & new_name & indexStr & file_extension as string) of me<br></br>  set the name of this_file to new_name & indexStr & file_extension as string<br></br> end repeat<br></br> display alert "All done! Renamed " & index & " files with '" & new_name & "' for you.  Have a great day!"<br></br>end tell<br></br><br></br>(***************************************************************************************<br></br> Default Action files are dragged to the app<br></br>***************************************************************************************)<br></br>on open of finderObjects -- catches drag'n'drop launches<br></br> set text item delimiters to "."<br></br> tell application "Finder"<br></br>  set all_files to every item of finderObjects<br></br>  display dialog "New File Name:" default answer ""<br></br><br></br>  set new_name to text returned of result<br></br>  repeat with index from 1 to the count of all_files<br></br><br></br>   set this_file to item index of finderObjects<br></br>   set file_name to get name of this_file<br></br>   set file_name_parts to text items of file_name<br></br>   if number of file_name_parts is 1 then<br></br>    set file_extension to ""<br></br>   else<br></br>    set file_extension to "." & item -1 of file_name_parts -- alternate is to use last item<br></br>   end if<br></br>   set indexStr to "-" & my add_leading_zero(index)<br></br>   -- display dialog "New name: " & new_name & indexStr & file_extension as string<br></br>   set the name of this_file to new_name & indexStr & file_extension as string<br></br>   -- my displayName(file_name)<br></br>   -- display dialog "File name: " & file_name<br></br>  end repeat<br></br>  display alert "All done! Renamed " & index & " files with '" & new_name & "' for you.  Have a great day!"<br></br> end tell<br></br>end open<br></br><br></br>(***************************************************************************************<br></br> LOCAL Handlers/Functions<br></br>***************************************************************************************)<br></br>(*<br></br> found this script at: http://ift.tt/1F7rsmz<br></br> I wanted to make sure that the numbers had leading zeros so they sort correctly.<br></br> I modified it as for this application I only need 10^1, not an arbitrary number of zeros.<br></br>*)<br></br>to add_leading_zero(this_number)<br></br> set max_leading_zeros to 1 as integer -- to make this arbitray move max_leading_zeros to an argument.<br></br> set the threshold_number to (10 ^ max_leading_zeros) as integer<br></br> if this_number is less than the threshold_number then<br></br>  set the leading_zeros to ""<br></br>  set the digit_count to the length of ((this_number div 1) as string)<br></br>  set the character_count to (max_leading_zeros + 1) - digit_count<br></br>  repeat character_count times<br></br>   set the leading_zeros to (the leading_zeros & "0") as string<br></br>  end repeat<br></br>  return (leading_zeros & (this_number as text)) as text<br></br> else<br></br>  return this_number as text<br></br> end if<br></br><br></br>end add_leading_zero<br></br><br></br>(*<br></br> Display a file name<br></br> Note, calling this function causes the application to run in the background.<br></br> Probably because... the message is sent to the background app while it is<br></br> the finder that is in the foreground.  <br></br>*)<br></br>on displayName(theFile) -- an example of doing something with each item<br></br> display dialog theFile as string<br></br>end displayName<br></br><br></br>

via Blogger http://ift.tt/1Ie7fre

Published by

scott