I have a folder structure with many levels of subfolders.
Via AppleScript, I’d like to be able to have Finder (in one window) select the most recently created file within each folder simultaneously.
I’ve taken a crack at a script of my own.
I seem to be having an issue.
I’m able to “display dialog” every file I want to be accessing, but I am unable to successfully store all those files within a list and select them.
I think my order of operations and my use of recursion isn’t too great - I’ll be the first to admit it 
Any help would be greatly appreciated - thanks very much!
on theSortOut(theMasterFolder)
tell application "Finder"
repeat with aFolder in theMasterFolder as specifier
if class of aFolder is folder then
my theSortOut(aFolder)
set theSort to sort files of aFolder by creation date
display dialog item -1 of theSort as text
end if
end repeat
end tell
end theSortOut
--
tell application "Finder"
set theExportsFolder to alias "Macintosh HD:Users:Kevin:Desktop:MASTER-FOLDER"
my theSortOut(theExportsFolder)
end tell
If I understand correctly, you may use :
on theSortOut(theMasterFolder)
tell application "Finder"
repeat with aFolder in theMasterFolder as specifier
if class of aFolder is folder then
my theSortOut(aFolder)
set theSort to sort files of aFolder by creation date
select item -1 of theSort
end if
end repeat
end tell
end theSortOut
--
tell application "Finder"
set theExportsFolder to alias ((path to desktop as text) & "MASTER-FOLDER")
open theExportsFolder
tell Finder window 1 to set current view to column view
my theSortOut(theExportsFolder)
end tell
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) vendredi 25 octobre 2019 17:31:44
Thanks for your reply!
The script you supplied made it so each file would open in its own separate Finder window, whereas I’m aiming for the script to select all of the appropriate Finder items within just one Finder window.
Do you think while in the repeat statement I’d be able to trap each “item -1 of theSort” into a list in order to use it outside of the repeat?
Thanks again!
That’s simply not possible. And it’s how Finder works, not a limitation of AppleScript.
Building that list is not the issue - it’s really what you want to do with them. Just selecting umpteen files does not seem very useful. There may be an entirely different way to get to your desired result.
It is possible:
global aSelection
on run
set theExportsFolder to choose folder
set aSelection to {}
tell application "Finder"
activate
open theExportsFolder
tell Finder window 1 to set current view to column view
set subFolders to folders of theExportsFolder
end tell
repeat with aFolder in subFolders
my sortOut(aFolder)
end repeat
-- Then, you can process selection as you want, for example:
-- repeat with aFile in aSelection
-- tell application "Finder"
-- select aFile
-- delay 1
-- close container window of container of aFile
-- end tell
-- end repeat
return aSelection
end run
on sortOut(aFolder)
tell application "Finder"
if (count of (files of aFolder)) > 0 then
set theSort to sort files of aFolder by creation date
set end of aSelection to last item of theSort
end if
set subFolders to folders of aFolder
repeat with aFolder in subFolders
my sortOut(aFolder)
end repeat
end tell
end sortOut
NOTE: To show selection’s files selected in 1 window, they must be in 1 folder. So, you can 1) create temporary folder 2) duplicate selection’s files to this folder 3) select and show them by Finder 4) delete temporary folder. For example, replace commented piece of code above with this:
set tempFolder to path to desktop folder
tell application "Finder"
set newFolder to make new folder at tempFolder with properties {name:"mySelectedFies"}
repeat with aFile in aSelection
try
set newFile to duplicate aFile to newFolder
end try
select files of newFolder
end repeat
delay 5
delete newFolder
end tell
But, as I think, aSelection list is all you need to process this files further… And, if you need choose some of this files further you can show them to user into 1 choose from list dialog:
global aSelection
on run
set theExportsFolder to choose folder
set aSelection to {}
tell application "Finder"
activate
open theExportsFolder
tell Finder window 1 to set current view to column view
set subFolders to folders of theExportsFolder
end tell
repeat with aFolder in subFolders
my sortOut(aFolder)
end repeat
tell me to activate
choose from list aSelection
end run
on sortOut(aFolder)
tell application "Finder"
if (count of (files of aFolder)) > 0 then
set theSort to sort files of aFolder by creation date
set end of aSelection to POSIX path of ((last item of theSort) as alias)
end if
set subFolders to folders of aFolder
repeat with aFolder in subFolders
my sortOut(aFolder)
end repeat
end tell
end sortOut
Exactly! But that was not what he asked; he wanted a selection in multiple folders in one window. And that is not possible.
Also, he seemed convinced he had to make that impossible selection, but did not tell us what his goal was. I believe it’s better to let him explain first, and then help him achieve a workable solution.
This uses ASObjC methods to identify the files because the Finder was taking rather a long time on my machine. The trick here is to open a list-view window on the top folder, fully expand all the subfolders, and select the identified files using ‘set selection’ rather than ‘select’. It works OK on my machine, but may need a delay at the end of the expandSubfolders() handler if the expansion’s not getting completed before the script tries to select the files.
use AppleScript version "2.5" -- El Capitan (10.11) or later
use scripting additions
selectMostRecentFiles()
on selectMostRecentFiles()
tell application "Finder"
activate
set topFolder to (choose folder with prompt "Select a folder….")
tell (make new Finder window to topFolder) to set its current view to list view
end tell
expandSubfolders()
set mostRecentFiles to getMostRecentFiles(topFolder)
tell application "Finder" to set selection to mostRecentFiles -- NB. 'set selection' here, not 'select'.
end selectMostRecentFiles
on expandSubfolders() -- Expand all folders in a list-view window.
tell application "System Events"
tell application process "Finder" to set frontmost to true
keystroke "a" using {command down} -- Select everything in the window.
key code 124 using {command down, option down} -- Expand the folders. (Command-Option-right arrow.)
end tell
-- Hopefully the folders will be fully expanded before the handler below has worked out what to select.
-- If not, add a delay here.
end expandSubfolders
on getMostRecentFiles(topFolder)
script o
use framework "Foundation"
property |⌘| : current application
property fileManager : missing value
property skipHiddenFiles : missing value
property creationDateKey : missing value
property allKeys : missing value
property directoryKeys : missing value
property directoryResult : missing value
property mostRecentFiles : {}
on init() -- Initialise some ASObjC values.
set fileManager to |⌘|'s class "NSFileManager"'s defaultManager()
set skipHiddenFiles to |⌘|'s NSDirectoryEnumerationSkipsHiddenFiles
set directoryKey to |⌘|'s NSURLIsDirectoryKey
set packageKey to |⌘|'s NSURLIsPackageKey
set creationDateKey to |⌘|'s NSURLCreationDateKey
set allKeys to |⌘|'s class "NSArray"'s arrayWithArray:({directoryKey, packageKey, creationDateKey})
set directoryKeys to |⌘|'s class "NSArray"'s arrayWithArray:({directoryKey, packageKey})
set directoryResult to |⌘|'s class "NSArray"'s arrayWithArray:({true, false})
end init
on gmrf(thisFolder) -- Recursive handler.
-- Get the contents of the current folder.
set theseContents to fileManager's contentsOfDirectoryAtURL:(thisFolder) includingPropertiesForKeys:(allKeys) options:(skipHiddenFiles) |error|:(missing value)
-- Initialise a collector for the URLs and creation dates of the files (including packages).
set fileData to |⌘|'s class "NSMutableArray"'s new()
repeat with thisURL in theseContents
set resourceValues to (thisURL's resourceValuesForKeys:(allKeys) |error|:(missing value))
-- Does this URL represent a directory? (42's just a convenient placeholder and has no significance here.)
if ((resourceValues's objectsForKeys:(directoryKeys) notFoundMarker:(42))'s isEqualToArray:(directoryResult)) then
-- If it does, check out the directory's contents recursively.
gmrf(thisURL)
else
-- Otherwise get the file's creation date.
set thisDate to (resourceValues's valueForKey:(creationDateKey))
-- Add a dictionary containing the URL and it to the current data collector.
set aDict to (|⌘|'s class "NSDictionary"'s dictionaryWithObjects:({thisURL, thisDate}) forKeys:({"URL", "creationDate"}))
tell fileData to addObject:({|URL|:thisURL, creationDate:thisDate})
end if
end repeat
if ((count fileData) > 0) then
-- If any data have been collected when all this folder's URLs have been checked, get the most recent creation date.
set mostRecentDate to fileData's valueForKeyPath:("@max.creationDate")
-- Reduce the data to just the one or more dictionaries containing this date.
set filter to |⌘|'s class "NSPredicate"'s predicateWithFormat_("creationDate == %@", mostRecentDate)
tell fileData to filterUsingPredicate:(filter)
-- Derive file specifier(s) from the corresponding URL(s) and concatenate these to the output list.
set mostRecentFiles to mostRecentFiles & (fileData's valueForKey:("URL")) as list
end if
end gmrf
end script
tell o
init()
gmrf(topFolder)
return its mostRecentFiles
end tell
end getMostRecentFiles