deleting empty folders

some workflows involve creating standard sets of job folders at the beginning of a project and then going through and cleaning out any unused folders at the end. this is a good way to standardise archiving procedures but it can also be tedious to clean up once the project is done. this post shows how to easily delete empty folders using applescript.

thanks to xander at cadcoder for the basic structure of the shell command.

Applescript Icon to follow along, copy and paste the script examples into applescript editor (found in applications > utilities) or, for older OS versions, script editor (applications > applescript). we’re going to set this one up as a droplet (so you’ll save it from script editor as an application). you can save a droplet to your desktop or drag it to your sidebar for easy access. to run the script just drag and drop a folder onto the droplet’s icon.

the basic form of the script goes like this :

on open mgItem
  do shell script "cd " & quoted form of POSIX path of mgItem & " && find . -type d -empty -delete;"
end open

in the shell, a folder is known as a directory (d). the first part of the command changes the current directory (cd) to our dropped folder. then it performs a search of that folder (find) for empty subfolders (-type d -empty) and deletes them. simple.

this works a treat — most of the time. but macs have these dastardly hidden files, the most common of which are the good old .DS_Store files which help the finder do its thing. a folder containing nothing but a .DS_Store file looks empty, but as far as the shell is concerned, it’s not.

so, here’s a variation to deal with that issue — first delete any .DS_Store files, then delete empty folders :

on open mgItem
  do shell script "cd " & quoted form of POSIX path of mgItem & " && find . -name .DS_Store -delete; find . -type d -empty -delete;"
end open

ok, that’s better. but to make the droplet a little more user-friendly, we should ensure it can handle multiple dropped folders — rather than having to drop them one at a time :

on open mgItems
  repeat with mgItem in mgItems
    do shell script "cd " & quoted form of POSIX path of mgItem & " && find . -name .DS_Store -delete; find . -type d -empty -delete;"
  end repeat
end open

and to make it more robust, it should not have a conniption if we inadvertently drop files instead of, or as well as, folders :

on open mgItems
  repeat with mgItem in mgItems
    set mgItem to mgItem as alias
    tell application "System Events" to set theClass to get class of item (mgItem as string)
    
    if (theClass as string) contains "cfol" then
      do shell script "cd " & quoted form of POSIX path of mgItem & " && find . -name .DS_Store -delete; find . -type d -empty -delete;"
    end if
    
  end repeat
end open

that’s about it — super fast, super easy way to clean out any unused folders.

for those interested in this sort of thing…
applescript droplet icon when an applescript is saved as a droplet, its icon includes a downwards pointing arrow. the on open mgItems line at the start of this script is what allows the saved application to run as a droplet. without that on open command you’d need to find some other way to reference the folders to be processed. renaming finder items shows a couple of other ways you could do this.

macgrunt icon

what dat?

.dat files are a pain — yet another reason to swear under your breath (or out loud if you prefer) at megasoft. they arrive in your inbox as win.dat or winmail.dat and trying to explain to the sender “yes, I know you sent me a pdf, but what I got was a dat…” is about as tedious as it gets. no doubt megasoft had some good reason to invent the transport neutral encapsulation format but that’s not helpful to a mac user in a hurry.

for those interested in this sort of thing, you can read more about the tnef format at wikipedia

TNEF's Enough icon TNEF’s Enough was created by a clever bloke called josh jacob. you can download this beaut little app from here. he’s offered this up as freeware, but feel free to make a donation.

it’s free and it works — bonza!

macgrunt icon

create folders from list II

the original create folders from list post prompted a question from Jocely. basically the question is… it’s all very good being able to create folders through applescript, but what about subfolders and whatnot? it’s such a great question — it needs its own post as a reply.

to run either of these scripts — copy it into script editor, save it out as an application, then double-click to run it. you’ll be prompted to select your csv file — then the folders will be created in the same location as the csv file.

ok, scripts build up over time — first you try something and, once you get it working, you add, refine, stabilise, improve, etc. that’s how this development progressed — the first stab at this challenge looks like this :

set mgCSVfile to choose file
open for access mgCSVfile
set mgList to (read mgCSVfile)
close access mgCSVfile

tell application "Finder"
  set mgFolder to container of mgCSVfile as text
  repeat with x from 1 to count paragraphs of mgList
    set text item delimiters of AppleScript to ","
    set mgThisList to text items of paragraph x of mgList as list
    set text item delimiters of AppleScript to ""
    
    set mgTopFolder to item 1 of mgThisList
    if (exists folder mgTopFolder of folder mgFolder) is false then
      make new folder at mgFolder with properties {name:mgTopFolder}
    end if
    set mgNewFolder to (folder mgTopFolder of folder mgFolder) as alias
    
    repeat with i from 2 to count mgThisList
      if item i of mgThisList is not "" then
        set mgSubFolder to item i of mgThisList
        if (exists folder mgSubFolder of folder mgNewFolder) is false then
          make new folder at mgNewFolder with properties {name:mgSubFolder}
        end if
      end if
    end repeat
    
  end repeat
end tell

… and it will render a csv file like this :
screen grab of basic csv file
… into a folder structure like this :
screen grab of first folder structure

well, that’s not a bad start. but what about a folder hierarchy a little more complex than that? we need to go deeper with the nesting. so here’s the second stab. and you’ll notice it’s actually a simpler script :

set mgCSVfile to choose file

open for access mgCSVfile
set mgList to (read mgCSVfile)
close access mgCSVfile

tell application "Finder"
  repeat with x from 1 to count paragraphs of mgList
    set mgFolder to container of mgCSVfile as text
    set text item delimiters of AppleScript to ","
    set mgThisList to text items of paragraph x of mgList as list
    set text item delimiters of AppleScript to ""
    
    repeat with i from 1 to count mgThisList
      if item i of mgThisList is not "" then
        set mgSubFolder to item i of mgThisList
        if (exists folder mgSubFolder of folder mgFolder) is false then
          make new folder at mgFolder with properties {name:mgSubFolder}
        end if
        set mgFolder to (folder mgSubFolder of folder mgFolder) as alias
      end if
    end repeat
    
  end repeat
end tell

… and the results using the same csv file :
screen grab of second folder structure

now we see that each line (paragraph) in the csv file renders a single nested folder structure. this is more like what we’re looking for. what do you reckon you’ll get if you run this csv file through that second script? :

screen grab of more complex csv file

you can get a copy of the CreateFoldersII app here

macgrunt icon

create folders from list

a recent digital publishing workflow required the creation of over 90 folders (one for each chapter of the book) and each of these also had to include a ‘links’ folder. imagine trying to do that manually — over 90 folders.

applescript droplet icon this is a perfect job for an applescript droplet — drop a text file on the app and watch the folders appear — as if by magic :

screen grab of finder before and after text file is dropped on droplet

this workflow starts with a comma delimited list of folder names. you could also use a tab delimited list. note: this version of the script does not handle returns (line breaks) in the list. the demo list looks like this :

screen grab of comma delimited list

you can get a copy of the CreateFolders app here

screen grab of create folders script compiled in script editor

for those interested in this sort of thing…
this script shows one way to strip leading and trailing spaces from chunks of text. it uses two repeat while loops, each of which keep repeating for as long as the associated statement is true. the repeat loop ceases as soon as the statement is false, and the script moves on.

you could use the repeat until form instead :
repeat until mgThisItem does not start with ” “

the last part of the script shows a simple, pure applescript way to create folders in the finder. the syntax is tortured and long-winded, but it works a treat. to learn how to create folders and folder hierarchies by scripting the shell, see nigel garvey’s excellent explanation at macscripter

macgrunt icon

renaming finder items II

renaming finder items introduced a couple of ways to batch-rename files in the finder using either automator or applescript, depending on the complexity of the job. those examples involved altering the existing filename by replacing characters or removing parts of the name. here’s another renaming workflow that was developed when one set of filenames needed to be mapped to a completely different set — hundreds of barcodes named by ISBN needed to be renamed by product code.

Applescript Icon applescript is fantastic for this kind of work because renaming hundreds of files by hand is just about as tedious as it gets. as with most scripting tasks, there are myriad ways this problem could be tackled — here’s just one :

screen grab showing filenames in excel

this solution starts with two lists — original filenames and new filenames — in a single excel worksheet. for this version of the app to work correctly, the worksheet needs to be saved in the same folder as the files to be changed and the worksheet needs to be open in excel.

the app looks through the top level of the folder for files and folders matching the names in column A and changes the filenames to the corresponding ones in column B — simple. files that don’t match a name in the list are skipped. all original file extensions are maintained. files in subfolders remain untouched. here’s a before and after shot of test files :

screen grab showing files before and after name changes

RenameByList is a zipped folder containing the app and a sample excel file. to use it — update the excel spreadsheet to your requirements, put all your files in the same folder and double-click the app :

you can get a copy of RenameByList here

screen grab showing compiled script in script editor

for those interested in this sort of thing…
excel can be a bit of a pain to script. for example, this is the command to extract the entries in column A :
set mgANames to formula of range mgARange

instead of giving us a list of names :

{"9781234567890", "9781234567891", "9781234567892" ...

this command gives us a list of lists :

{{"9781234567890"}, {"9781234567891"}, {"9781234567892"} ...

that’s why we need to loop through the original list (mgANames) with this command — to convert the list of lists into a straight list :
set end of mgOriginalNames to item 1 of item x of mgANames

the other way would be to just loop through the cells in excel to make the list in one pass like this :

tell used range to set mgRowCount to count rows
repeat with x from 2 to mgRowCount
  set end of mgOriginalNames to formula of cell ("A" & x)
  set end of mgNewNames to formula of cell ("B" & x)
end repeat

but this script was developed and tested through script editor before being saved out as an app. and this second method is MUCH slower through script editor (although not much different when run as an app). try it yourself.

macgrunt icon