Just wanted to apologise fist as I have ZERO KNOWLEDGE on this.
I’ve been exploring the Automator app and it seems like it won’t help me that much as I also need to to type in each texts manually.
I wanted an automation to sort my files by creating folders for the files containing the same text/characters.
Sample files:
IMG_0001.jpg
IMG_0002.jpg
IMG_0003.jpg
PIC_0001.jpg
PIC_0002.jpg
PIC_0003.jpg
PHO_0001.jpg
PHO_0002.jpg
PHO_0003.jpg
Output I want through automation
IMG FOLDER
IMG_0001.jpg
IMG_0002.jpg
IMG_0003.jpg
PIC FOLDER
PIC_0001.jpg
PIC_0002.jpg
PIC_0003.jpg
PHO FOLDER
PHO_0001.jpg
PHO_0002.jpg
PHO_0003.jpg
I have hundreds of these to sort and It’s taking me time to do this manually.
I have the list of texts (IMG, PIC, PHO, etc.) that I need to sort in a spreadsheet.
Where are the sample files? in one folder, or in multiple folders in multiple locations?
Where do you want the new folder to be created? In a predetermined location, or the same location as the input files (provided they are all in one folder to begin with), or in a location that the user chooses each time the script is run?
Your original question has many vagueries you didn’t provide for.
This is a simple script which first asks for a base folder.
Then it gets the file names in this folder and checks if the names end with jpg and if the fourth character is an underscore.
On success the three letter subfolder is being created (if it doesn’t exist yet) and the image is moved to that folder
set baseFolder to POSIX path of (choose folder with prompt "Choose the image folder")
set theImages to list folder baseFolder without invisibles
repeat with anImage in theImages
if anImage ends with "jpg" and (get offset of "_" in anImage) is 4 then
set destinationFolder to baseFolder & text 1 thru 3 of anImage & "/"
do shell script "/bin/mkdir -p " & quoted form of destinationFolder
do shell script "mv " & quoted form of (baseFolder & anImage) & space & quoted form of (destinationFolder & anImage)
end if
end repeat
Just view the folder as list, sorted by name. All the IMG files will be next to each other. So will the PIC and PHO files. select each group and move to their respective folders. 20 seconds max.
Here is my script that doesn’t use “do shell script”…
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
property extList : {"IMG", "PIC", "PHO"}
local myFolder, myFiles, anItem, ext
set myFolder to choose folder with prompt "Select folder that contains images to sort…"
set myFolder to myFolder as text
repeat with anItem in extList
try
alias (myFolder & anItem)
on error
tell application "System Events"
make new folder at folder myFolder with properties {name:anItem}
end tell
end try
end repeat
tell application "System Events"
set myFiles to files of folder myFolder
repeat with anItem in myFiles
set anItem to contents of anItem
if (name extension of anItem) = "jpg" then
repeat with ext in extList
if name of anItem begins with ext then
move anItem to folder (myFolder & ext)
exit repeat
end if
end repeat
end if
end repeat
end tell
It should be faster on large number of files. I haven’t tested tho.
Here is a slightly better version with fewer repeat loops…
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
property extList : {"IMG", "PIC", "PHO"}
local myFolder, myFiles, anItem, ext
set myFolder to choose folder with prompt "Select folder that contains images to sort…"
set myFolder to myFolder as text
repeat with anItem in extList
try
alias (myFolder & anItem)
on error
tell application "System Events"
make new folder at folder myFolder with properties {name:anItem}
end tell
end try
end repeat
tell application "System Events"
set myFiles to files of folder myFolder
repeat with anItem in myFiles
set anItem to contents of anItem
if (name extension of anItem) = "jpg" then
set ext to name of anItem
set ext to text 1 thru 3 of ext
if ext is in extList then move anItem to folder (myFolder & ext)
end if
end repeat
end tell
This is a very odd decision to use the resolution of an alias reference as a test to determine whether or not a folder exists, given that every single other line in the script relies on calling out to System Events, which provides a means to test for the existence of filesystem paths (namely, the exists command) that is going to be faster than trying to resolve an alias.
That said, you dont actually need to test for existence, as System Events’s make command doesn’t complain if the path already exists, provided that it points to the same type of object that the command is being asked to create. So you can essentially get away with simply doing this:
repeat with anItem in extList
tell application "System Events"
make new folder at folder myFolder with properties {name:anItem}
end repeat
But, the truly robust approach would involve testing for existence, just in case there happens to be something at the path <myFolder>/<anItem> that turned out not to be a folder:
repeat with anItem in extList
tell application "System Events"
tell folder myFolder to if not (item anItem exists) then
make new folder with properties {name:anItem}
end if
end tell
end repeat
Yes and no. It’s not the case that your “native call” saves you from having to call out to some other application (ie. System Events). Your entire script invokes System Events, save for this one decision to go “native”. Therefore, you’re not really saving any time at all.
That’s not a very meaningful statement on its own. For one, a result that varies by up to 25% immediately tells you it’s not reliable.
But I’m not contesting the idea that alias resolution can and often will be faster than calling out to System Events, where these two things are happening in a vacuum. I’m suggesting that your script is calling out to System Eventsanyway, so it seems like a peculiar decision to make this one exception, citing execution speed as the reason, and then implementing the method in a sub-optimal manner.
For instance, coercing to an alias (...as alias) is no slower than using alias aa an object specifier when the path resolves, but fails far sooner when the path doesn’t. Then, in the cases of failure, throwing and catching an exception takes more time than providing an alternative class to allow coercion to take place and using this to indicate that alias resolution failed.
There’s also the issue that simply testing the resolution of an alias isn’t sufficient to determine that what it points to is a folder, however this is an easy solve.
There’s no right or wrong way to do any of this, and we all have our own individual preferences and stylistic choices. If nothing I’ve written is new to you, then hopefully it might be something new for others to contemplate on and experiment with. Onwards and upwards, as they say.