I’m having trouble figuring this one out. I could brute- force the issue, but I think there must be a more elegant way to solve this.
I would like to find the most recent file in a given folder, by creation date. I can get all the creation dates of the file items, but then I have to somehow associate those most recent dates with the file’s actual name (so I can open it). It’s quite ugly – at least the way I do it it’s ugly…
I tried ordering the Finder window by column view sorted on Creation Date, but I can’t get the particular folder window I want to open. I thought the first item in that list would be the one I want, but I can’t get it to work.
I’d very much appreciate any help anyone can offer.
choose folder with prompt "Find newest file in this folder:"
set sourceFolder to result
tell application "Finder"
sort (get files of sourceFolder) by creation date
-- This raises an error if the folder doesn't contain any files
set theFile to (item 1 of result) as alias
end tell
Note that the Finder’s sort command requires Mac OS X v10.4 or later.
I keep the “FinderSort().scpt” file in a folder call “Libraries” in my “Scripts” folder and load it into any of my Jaguar scripts that need it. An adaptation of Bruce’s script to use it like this would be:
-- Load the FinderSort() script file into this script.
set FSort to (load script file ((path to scripts folder as Unicode text) & "Libraries:FinderSort().scpt"))
choose folder with prompt "Find newest file in this folder:"
set sourceFolder to result
tell application "Finder"
-- FinderSort() needs a Finder reference, not a list.
set f to a reference to files of folder sourceFolder
FSort's FinderSort(f, "modification date")
-- This raises an error if the folder doesn't contain any files
set theFile to (item 1 of result) as alias
end tell
.
The Finder sometimes accepts a path string instead of a proper file or folder reference, but doesn’t in this case. It would be better to coerce the path to an alias:
set sourceFolder to "HD:Top Level Folder:Sub Folder:One More Sub Folder:Target Folder" as alias
. and/or to put the word ‘folder’ in front it inside the Finder ‘tell’ block:
tell application "Finder"
sort (get files of folder sourceFolder) by creation date
-- This raises an error if the folder doesn't contain any files
set theFile to (item 1 of result) as alias
end tell
set sourceFolder to "HD:Top Level Folder:Sub Folder:One More Sub Folder:Target Folder:"
tell application "Finder" to set theFile to 1st file of folder sourceFolder whose creation date is (last item of my bubblesort(get creation date of files of folder sourceFolder))
on bubblesort(array)
repeat with i from length of array to 2 by -1 --> go backwards
repeat with j from 1 to i - 1 --> go forwards
tell array
if item j > item (j + 1) then
set {item j, item (j + 1)} to {item (j + 1), item j} -- swap
end if
end tell
end repeat
end repeat
return array
end bubblesort
set sourcePath to "HD:Top Level Folder:Sub Folder:One More Sub Folder:Target Folder:" as Unicode text
tell application "Finder" to set {fileNames, modDates} to {name, modification date} of files of folder sourcePath
set n to 1
set latestDate to beginning of modDates
repeat with i from 2 to (count modDates)
set thisDate to item i of modDates
if (thisDate comes after latestDate) then
set n to i
set latestDate to thisDate
end if
end repeat
set theFile to alias (sourcePath & item n of fileNames)
Thank you guys so much for your help. It’s made a huge difference in my script.
I was reading over and trying to understand Stefan’s solution (along with Nigel’s), when Nigel made his latest response. It is so elegant, so simple, and so beautifully written – it’s a work of art.
This seemed simple enough but am having no luck getting it to work.
Just need to get the most recent file in the folder.
set sourceFolder to "Macintosh HD:Users:TV:Sites:ss2"
tell application "Finder"
sort (get files of sourceFolder) by creation date
-- This raises an error if the folder doesn't contain any files
set theFile to (item 1 of result) as alias
end tell
The error it returns is: Can’t get every file of “Macintosh HD:Users:TV:Sites:ss2”.
There are two files in the folder with different creation dates.
I’m running 10.5.8
set sourceFolder to "Macintosh HD:Users:TV:Sites:ss2" as alias
tell application "Finder"
sort (get files of folder sourceFolder) by creation date
-- This raises an error if the folder doesn't contain any files
set theFile to (item 1 of result) as alias
end tell
Getting this error: Can’t make item 1 of {} into type alias.
I fixed that one for you, but now, if you have some more stuff to do with theFile, then you should do that within the if block. (Just mentioning it.)
tell application "Finder"
try
set sortedList to sort (get files of folder sourceFolder) by creation date
end try
if sortedList is not {} then
set theFile to (item 1 of sortedList) as alias
end if
end tell
Thanks a bunch for the fix. Works great. I see now my security camera app is creating new
folders within the ss2 folder each time I set it to record a video file.
Have to try to work that out as well. Might you know if it’s possible to search subfolders as well within ss2?
Thanks,
Carl
set sourceFolder to "Macintosh HD:Users:TV:Sites:ss2"
tell application "Finder"
try
set sortedList to sort (get files of folder sourceFolder) by creation date
end try
if sortedList is not {} then
set theFile to (item 1 of sortedList) as alias
return theFile
end if
end tell
I think I know of a couple of ways to get the lastest modified file in a folder hierarchy.
We can’t use finder for that, so first I want to know, (and I’m not even sure if that is the way I want to go) does ASOC work for you? -I believe you use the indigo server, what I want to know, is whether you use Mavericks, and then if the ASOC statements within an “indigo” script, together with ASOC libraries works for you.
If you don’t know, and don’t care to find out, then that is fine, but this is the fastest way to go.
Save the script below as a Script Bundle with AppleScript editor, click the drawer icon and hook off for ASOC library, with the name ASOCTest, in your ~/Library/Script Libraries folder. (Make it if it isn’t there).
use AppleScript version "2.3"
use scripting additions
on testit()
tell (path to frontmost application as text)
tell me
display dialog "it works"
end tell
end tell
end testit
Now, stuff the script below into an indigo script window, and try to run it.
use AppleScript version "2.3"
use scripting additions
use asoct : script "ASOCTest"
asoct's testit()
No doubt that would be an excellent way to go but my indigo server is
running 10.5.8. I have used ASOC for other tasks on other machines and it does work very well.
What I wonder is, is if there always are just going to be a small number of files there, and that the folder hierarchy is not deep, like 3-4 levels or deeper.
Then I think we can implement a solution with Finder first, to see if that works out, or if the consisistency of your root folder is different, then we go straight for a do shell script involving mdfind and sort.
Please see if this works for you. The script below is supposed to work under OS X 10.5, and won’t work under Mavericks, since .DS_Store files are visible, and the files are sorted in the opposite direction.
set sourceFolder to "Macintosh HD:Users:TV:Sites:ss2"
tell application "Finder"
return item 1 of (sort (every file of entire contents of folder sourceFolder) by modification date) as alias
end tell
That one is working but it does return the oldest file, not the newest.
The source folder may contain a number of folders, but would never be more than 1 folder deep.
The Finder doesn’t return “.DS_Store” files, so the repeat’s not necessary. The script object’s not necessary in any case.
The result of sorting by dates with the Finder has recently changed, probably by accident, since it hasn’t been announced. In Mavericks, dates are sorted from oldest to most recent, rather than vice versa as before. McUsrII’s script gets the most recently modified file in Mavericks or the earliest otherwise. If you’re going to use the Finder’s ‘sort’, you either have to test the system and take the appropriate action, or get both the first and last items in the list and see which is younger.