Hello, I have a question if anyone could help me figure it out. I’m I’ve basically got some files in Finder that are selected, and the files are set up in alphabetical order. (They’re gifs that will be joined into a larger gif using FFMPEG so the order is important.) For some reason, Finder in Big Sur is being difficult to work with. I would hope that this code
tell application "Finder"
set theSel to (get selection as alias list)
set path1 to POSIX path of (item 1 of theSel as alias)
end tell
would give me the path to the first item my selection as sorted by alphabetical order in the filename…but bizarrely, it’s assuming the first file I clicked on when making my selection is “item 1,” the second item I clicked on is “item 2” and so on.
I can’t find any easy way to get the finder selection and sort it, or otherwise work with by filename order, modification order, or anything.
I know this was in direct response to the OP, but as I’m sure you know, the Finder is often (always?) slow. This script took 14.87 sec to process 476 items on my fast 2019 iMac.
Is there a better (ASObjC?) solution for sorting that would be much faster, even if you have to start with the Finder’s selection?
If you want to sort by some property of URLs, such as the name (or lastPathComponent) as here, it’s reasonably simple and should be a bit faster:
use scripting additions
use framework "Foundation"
tell application "Finder"
set theSel to selection as alias list
end tell
set theArray to current application's NSArray's arrayWithArray:theSel
-- make a sort descriptor that describes the key to sort on
set theDescriptor to current application's NSSortDescriptor's sortDescriptorWithKey:"lastPathComponent" ascending:true selector:"localizedStandardCompare:" -- Finder-style sorting
-- sort the array
set theList to (theArray's sortedArrayUsingDescriptors:{theDescriptor}) as list
If you want to support by something that’s not a simple property, such as modification date, you need a repeat loop to get the date from each URL separately, so the gain might not be worth it.
Thanks to @ShaneStanley and his BridgePlus script library, and his many posts, I have been able to put together a handler that lets you sort a file list based on any property of the file. Specifically this test script sorts on file modification date.
Sorts 551 Finder Items by Mod Date in 2.35 sec.
Thanks again, Shane.
Disclaimer: This script uses the deprecated info for command, which I really like and continues to work. I’m sure there is a System Events command that would also work.
property ptyScriptName : "How To Sort Finder Selection Based on Date"
property ptyScriptVer : "1.0"
property ptyScriptDate : "2021-05-22"
property ptyScriptAuthor : "JMichaelTX"
(*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PURPOSE:
• How To Sort Finder Selection Based on Date -- Uses BridgePlus
RETURNS: List of File POSIX Paths Sorted by Modification Date
REQUIRED:
1. macOS 10.11.6+
2. Mac Applications
• Finder
3. Script Libraries
• BridgePlus by @ShaneStanley
TAGS: @SW.Finder @Lang.AS @Lang.ASObjC @CAT.Files @CAT.Sort @type.Example @Auth.Shane
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*)
use AppleScript version "2.5"
use scripting additions
use framework "Foundation" -- Required for all ASObjC commands
use BPLib : script "BridgePlus" -- Required for sortMultiLists()
tell application "Finder"
set fileList to selection as alias list
end tell
set dateList to {}
repeat with oFileAlias in fileList
set oFile to info for oFileAlias
set end of dateList to modification date of oFile -- (info for oFile)
set contents of oFileAlias to POSIX path of oFileAlias
end repeat
--- SORT First on Mod Date (Desc), and then on File Path (Asc) ---
set {dateList, fileList} to my sortMultiLists({dateList, fileList}, {"DESC", "ASC"})
return fileList
--> Sorts 551 Finder Items by Mod Date in 2.35 sec
--~~~~~~~~~~~~~~~~~~~~~~~ END OF MAIN SCRIPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
on sortMultiLists(pListOfLists, pSortDirList) -- @Lists @Sort @BridgePlus @ASObjC
--–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
(* VER: 1.0 2020-11-23
PURPOSE:
PARAMETERS:
• pListOfLists | list | List that contains two or more lists to be sorted
• Lists will be sorted by each sub-list in the order entered.
• pSortDirList | list | List of text items indicating the sort direction for each list
• Must be "ASC" (for ascending) or
• "DESC" (for descending)
RETURNS: List of Lists in Sorted Order
AUTHOR: JMichaelTX
REQUIRES:
use framework "Foundation"
use BPLib : script "BridgePlus"
REF: BridgePlus 1.3.3 Script Library, Shane Stanley
https://latenightsw.com/support/freeware/
--–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
*)
local rowsList, listCount, sortByList, iL, oSort
--- Setup the Sort ---
set rowsList to BPLib's colsToRowsIn:pListOfLists
set listCount to count of pListOfLists
set sortByList to {}
--- Sort Order by List as Passed in pListOfLists ---
repeat with iL from 1 to listCount
set end of sortByList to iL
end repeat
--- Convert Text Sort Direction to Boolean ---
-- (true means ascending)
repeat with oSort in pSortDirList
set contents of oSort to ((oSort as text) starts with "ASC")
end repeat
--- Do the Sort
set rowsList to BPLib's sublistsIn:rowsList sortedByIndexes:sortByList ascending:pSortDirList sortTypes:{}
--- Get Sort Results ---
set pListOfLists to BPLib's colsToRowsIn:rowsList
return pListOfLists
end sortMultiLists
--~~~~~~~~~~~~~~~~~~~~ END of Handler ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If you’re happy to use that, this should be a bit faster:
use scripting additions
use framework "Foundation"
use script "BridgePlus"
tell application "Finder"
set theSel to selection as alias list
end tell
load framework
set theArray to current application's SMSForder's resourceValuesForKeys:{current application's NSURLContentModificationDateKey, current application's NSURLPathKey} forURLsOrFiles:theSel
-- make a sort descriptor that describes the key to sort on
set theDescriptor to current application's NSSortDescriptor's sortDescriptorWithKey:(current application's NSURLContentModificationDateKey) ascending:false
-- sort the array
set theList to ((theArray's sortedArrayUsingDescriptors:{theDescriptor})'s valueForKey:(current application's NSURLPathKey)) as list