Reputation: 3
I'm writing an Applescript which prompts the user to select a folder that it will then run the script on. The script runs and basically sorts files into folders. At the end of the script, I want the empty folders to be deleted.
The script works wonderfully until I want to delete the empty folders at the end.
This is what picks the folder:
tell application "Finder"
set packageFolder to (choose folder with prompt "Please choose your
logo package folder") as string
end tell
And this is the code to delete the empty folders:
tell application "Finder"
repeat with oneFolder in (get folders of packageFolder)
if (count items) of oneFolder is 0 then delete oneFolder
end repeat
end tell
I get the following error:
Result:
error “Can’t get every folder of |”Macintosh HD:Users:michael: Desktop:Logo Package Script Test:\”.” number -1728 from every class cfol» of “Macintosh HD:Users:michael: Desktop: Logo Package Script Test:”
What am I doing wrong here?
Upvotes: 0
Views: 2132
Reputation: 25042
The answers provided here and here in this thread, consider any folder which contains only hidden1 files and/or hidden folders to be empty too - resulting in them being deleted, which may lead to the loss of important data.
Using the following solution an empty folder is considered to be empty, only if it does not contain a file(s) and/or non-empty folder(s) - whether they're visible or hidden. However, the exception to this rule is for any folder containing only a hidden .DS_Store
file - they will be considered empty, and therefore deleted too.
This solution utilizes the Bash find
command and executes it via AppleScripts do shell script
command.
tell application "Finder"
set packageFolder to choose folder with prompt "Please choose your logo package folder"
set posixPath to quoted form of POSIX path of packageFolder
do shell script "find " & posixPath & " -name '.DS_Store' -type f -delete && find " & posixPath & " -empty -type d -delete"
end tell
Essentially, this AppleScript executes the following Bash commands:
find /path/to/directory/ -name '.DS_Store' -type f -delete
find /path/to/directory/ -empty -type d -delete
Let's breakdown the parts of those two commands for a better understanding of what's happening:
The first command:
find
- Search a folder hierarchy for file and folder name(s) which meet a given criteria.
path/to/directory/
- This (contrived) path points to the directory where the search should begin from. This will be replaced with a real path, i.e. the path to whichever folder is chosen and assigned to the packageFolder
variable via the choose folder
command.
We provide that path (as a POSIX path
) to the do shell script
command via the part which reads:
set posixPath to quoted form of POSIX path of packageFolder
The quoted form
part ensures the folder path, (i.e. the one assigned to the posixPath
variable), is provided to do shell script
avoiding further interpretation by the shell - it essentially ensures the path to the chosen folder, whose name may include spaces, is handled correctly.
-name
- The name of the file to search for, i.e. .DS_Store
.
-type f
- This option specifies that we only want to include a regular file.
-delete
- This option deletes all files which match the previously specified criteria, i.e. files named .DS_Store
.
The second command:
find
- as per the first command.path/to/directory/
- as per the first command.
-empty
- This option specifies that we want to include either a regular file or a directory only if it is empty.
-type d
- This option specifies that we only want to include directories.
-delete
- as per the first command., however this time we delete empty folders only.
Given a chosen source directory tree like this:
.
├── a
│ ├── .hidden-dir-a
│ │ └── foo.txt
│ └── .hidden-dir-b
├── b
│ └── bb
│ ├── .DS_Store
│ └── bbb
├── c
│ └── .hidden.txt
└── d
├── dd
│ └── ddd
└── quux.txt
The resultant directory tree (i.e. after running the AppleScript) will be:
.
├── a
│ └── .hidden-dir-a
│ └── foo.txt
├── c
│ └── .hidden.txt
└── d
└── quux.txt
The current AppleScript (above) assumes that you're using the path which is assigned to the packageFolder
variable elsewhere in your script, hence it hasn't been changed. Consequently, it introduces the line which reads;
set posixPath to quoted form of POSIX path of packageFolder
to obtain a POSIX path equivalent to the chosen folder path.
However, If the packageFolder
variable is not used elsewhere, you could refactor the script to the following instead:
tell application "Finder"
set packageFolder to quoted form of (POSIX path of (choose folder with prompt "Please choose your logo package folder"))
do shell script "find " & packageFolder & " -name '.DS_Store' -type f -delete && find " & packageFolder & " -empty -type d -delete"
end tell
1 Hidden files and folders on MacOS are those whose name begins with a dot (.
). For instance .gitignore
Upvotes: 2
Reputation: 3
This is what ended up working:
on killEmpty(fol)
tell application "Finder"
repeat with f in (get fol's folders)
my killEmpty(f)
end repeat
if (count items of fol) is 0 then delete fol
end tell
end killEmpty
tell application "Finder"
repeat with f in (get folders of folder packageFolder)
my killEmpty(f)
end repeat
end tell
I found this solution here: https://discussions.apple.com/message/20188767#message20188767
Thanks again everyone. Sorry about the inaccurately worded question.
Upvotes: 0
Reputation: 3142
This works for me on the latest version of macOS High Sierra
set packageFolder to (choose folder with prompt "Please choose your
logo package folder") as string
tell application "Finder"
set theFolders to folders of entire contents of folder packageFolder
repeat with i from 1 to count of theFolders
set thisFolder to item i of theFolders
if (count of items of thisFolder) is equal to 0 then
delete thisFolder
end if
end repeat
end tell
Upvotes: 0