Just wondering how I can find the file in a directory, with the most recent “date modified”. Currently I have the following, but I don’t think it’s going to work as files are created and updated at various times.
tell application "System Events"
set the_file to the last file of folder holder_folder
end tell
Your script returns a value but we don’t know which criterium is applied to define the last file.
I dislike the Finder but for this task, I would use it.
set theFolder to choose folder
tell application "Finder" to tell folder theFolder
set sortedList to sort every file by modification date
set {firstItem, lastItem} to {item 1 of sortedList as alias, item -1 of sortedList as alias}
# As Invisible files are visibles on my machine I added an extraneous instruction
if name of lastItem is ".DS_Store" then set lastItem to item -2 of sortedList as alias
end tell
lastItem
With a bit of luck, Shane Stanley will post a more efficient code using ASObjC.
Yvan KOENIG running Yosemite 10.10.4 in French (VALLAURIS, France) mercredi 12 août 2015 19:14:18
set theFolder to (choose folder) as text
tell application "Finder"
set the_file to last item of (sort (get files of folder theFolder) by modification date)
end tell
No-one will use because it’s significantly longer code:
use AppleScript version "2.3"
use scripting additions
use framework "Foundation"
set folderPosixPath to POSIX path of (choose folder)
its mostRecentlyModifiedIemIn:folderPosixPath
on mostRecentlyModifiedIemIn:folderPosixPath
set theNSURL to current application's class "NSURL"'s fileURLWithPath:folderPosixPath -- make URL for folder because that's what's needed
set theNSFileManager to current application's NSFileManager's defaultManager() -- get file manager
-- get contents of the folder
set keysToRequest to {current application's NSURLPathKey, current application's NSURLContentModificationDateKey} -- keys for values we want for each item
set theURLs to theNSFileManager's contentsOfDirectoryAtURL:theNSURL includingPropertiesForKeys:keysToRequest options:(current application's NSDirectoryEnumerationSkipsHiddenFiles) |error|:(missing value)
-- get mod dates and paths for URLs
set theInfoNSMutableArray to current application's NSMutableArray's array() -- array to store new values in
repeat with i from 1 to theURLs's |count|()
set anNSURL to (theURLs's objectAtIndex:(i - 1)) -- zero-based
(theInfoNSMutableArray's addObject:(anNSURL's resourceValuesForKeys:keysToRequest |error|:(missing value))) -- get values dictionary and add to array
end repeat
-- sort them in date order
set theNSSortDescriptor to current application's NSSortDescriptor's sortDescriptorWithKey:(current application's NSURLContentModificationDateKey) ascending:false -- describes the sort to perform
theInfoNSMutableArray's sortUsingDescriptors:{theNSSortDescriptor} -- do the sort
-- get the path of the first item
return ((theInfoNSMutableArray's objectAtIndex:0)'s valueForKey:(current application's NSURLPathKey)) as text -- extract path and convert to text
end mostRecentlyModifiedIemIn:
In my tests, that takes about 1/40th of the Finder equivalent.
What’s the problem ?
When we have the code available in a bank of handlers, its length doesn’t matter.
Copy Paste inserts it in the real script in a snap.
I’m just wondering upon the way your script drops .DS_Store.
On my machine this file is visible and is the more recently modified but happily it’s not the one returned.
StephanK’s one returns this generally hidden file as the last modified one.
Yvan KOENIG running Yosemite 10.10.4 in French (VALLAURIS, France) jeudi 13 août 2015 10:26:11
If I throw in as alias list I seem to get slightly quicker results, or am I just imagining it?
set theFolder to (choose folder) as text
tell application "Finder"
set the_file to last item of (sort (get files of folder theFolder as alias list) by modification date)
end tell
Thanks for the confirmation and explanation Stefan.
Following one of your posts ages ago I tend to always throw in as alias list when getting a file list like that.
It seems that I must understand that NSDirectoryEnumerationSkipsHiddenFile filter files whose name starts with “.” even when they aren’t hidden. It’s not the Finder’s behavior.
On my mac, “hidden files” are always visible so I took care of .DS_Store in my original answer.
Maybe it would be better to filter every file whose name starts with a dot.
Yvan KOENIG running Yosemite 10.10.4 in French (VALLAURIS, France) jeudi 13 août 2015 12:25:31
To make it clear this is the behavior of the usual ways to list files in the file system.
System Events displays always all files including hidden files. Cocoa displays all files including hidden files unless you set the option NSDirectoryEnumerationSkipsHiddenFiles Finder displays hidden files depending on the preference key AppleShowAllFiles
System Events and Cocoa don’t consider the Finder preference at all.
I guess that 95% of the users have AppleShowAllFiles set to the default value, false.
As Stefan said, the Finder takes the Finder’s settings into account. I don’t think anything else does; for example, choose file has its own parameter for whether to include invisible files.
A minor thing: NSDirectoryEnumerationSkipsHiddenFiles skips files where the name begins with “.”, plus files that have the hidden attribute (NSURLIsHiddenKey) set.
Better still, put it in a library. But I think there’s still a strong perception that more code = slower. Particularly in a language with the performance peculiarities of AppleScript, there’s rarely much correlation.
Out of interest try this variation to see a speed jump.
set theFolder to (choose folder) as text
tell application "Finder"
set the_file to last item of (sort (get files of folder theFolder as alias list) by modification date)
end tell
set theFolder to (choose folder)
tell application "Finder"
set the_file to last item of (sort (get files of theFolder as alias list) by modification date)
end tell
If you are interested by speed, I just wish to say that Shane Stanley gave a code which is 14 times faster than the “optimized” Finder version (40 times faster than the “non optimized” one).
It’s not because a script listing is shorter than an other one that it is faster.
Yvan KOENIG running Yosemite 10.10.5 in French (VALLAURIS, France) lundi 17 août 2015 11:01:04
No need for ASObjC Runner, just running under Yosemite (or El Capitan)
Are you sure that you inserted the three instructions available at the beginning of Shane’s proposal ?
I ask that because the script compiles without them but of course it fails.
Without the 3 instructions the error message would be : class “NSURL” ne comprend pas le message « fileURLWithPath_ ».
Yvan KOENIG running Yosemite 10.10.5 in French (VALLAURIS, France) lundi 17 août 2015 12:05:07
P.S. In fact, we may also use it under Mavericks but in this case, the handler must be saved inas a library which must be “blessed” and stored in a dedicated location :
“/Library/Script Libraries/”
or
“~/Library/Script Libraries/”