You are not logged in.
HI folks.
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.
Applescript:
tell application "System Events"
set the_file to the last file of folder holder_folder
end tell
Offline
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.
Applescript:
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
Offline
Hi,
the Finder has a sort function
Applescript:
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
regards
Stefan
Offline
With a bit of luck, Shane Stanley will post a more efficient code using ASObjC.
No-one will use because it's significantly longer code:
Applescript:
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.
Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com
Offline
Thanks Shane
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
Offline
StephanK's one returns this generally hidden file as the last modified one.
Yvan,
the Finder terminology considers the preference key AppleShowAllFiles which is (supposed to be) set to false by default.
Shane's script skips hiiden files by passing the option NSDirectoryEnumerationSkipsHiddenFiles
Last edited by StefanK (2015-08-13 04:51:25 am)
regards
Stefan
Offline
Hi,
the Finder has a sort functionApplescript:
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
If I throw in as alias list I seem to get slightly quicker results, or am I just imagining it?
Applescript:
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
Last edited by TecNik (2015-08-13 02:41:42 am)
Offline
If I throw in as alias list I seem to get slightly quicker results, or am I just imagining it?
It's indeed faster because the overhead to create the Finder object descriptor chain (file … of folder … of folder … of startup disk) can be omitted
regards
Stefan
Offline
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.
Last edited by TecNik (2015-08-13 03:03:01 am)
Offline
Yvan Koenig wrote:StephanK's one returns this generally hidden file as the last modified one.
Yvan,
the Finder terminology considers the preference key AppleShowAllFiles which is (supposed to be) set to false by default.
Shane's script skips hiiden files by passing the option NSDirectoryEnumerationSkipsHiddenFile
Thanks
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
Last edited by Yvan Koenig (2015-08-13 04:27:15 am)
Offline
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.
Last edited by StefanK (2015-08-13 04:50:50 am)
regards
Stefan
Offline
If I throw in as alias list I seem to get slightly quicker results, or am I just imagining it?
Not at all. Putting it in, the ASObjC version is only about 16 times faster, compared with 40 times faster otherwise.
Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com
Offline
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.
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.
Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com
Offline
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.
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.
Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com
Offline
Hi,
the Finder has a sort functionApplescript:
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
Oh very good. That's what I was looking for. I knew there was a way to target it.
Cheers. Works like a charm.
Offline
TecNik wrote:If I throw in as alias list I seem to get slightly quicker results, or am I just imagining it?
It's indeed faster because the overhead to create the Finder object descriptor chain (file … of folder … of folder … of startup disk) can be omitted
Out of interest try this variation to see a speed jump.
Applescript:
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
It's a little trick I learnt off Stefan.
Offline
Is it faster than :
Applescript:
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
Last edited by Yvan Koenig (2015-08-17 03:05:26 am)
Offline
Thanks Yvan.
Yeah, I understand it's not because the code listing is shorter
Do we need ASObjC Runner present to get Shane's code to work? I could compile it but when executed I got an error.
TIA
Offline
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/"
Last edited by Yvan Koenig (2015-08-17 04:09:58 am)
Offline
Thanks for the info Yvan, think you may have nailed it in your P.S.
I'm on Mavericks, and I was getting the error 'Can't find framework "Foundation" of <<script>>. Access not allowed.'
Please can you explain what you mean by 'blessed'? Are you just talking about access privileges?
TIA
Offline
TecNik,
This gives a good explanation with screen shots:
macosxautomation.com/mavericks/libraries/asoc.html
There's also a more detailed explanation here:
macscripter.net/viewtopic.php?id=41638
Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com
Offline
OK, I am not a sooth sayer so I can't guess which operating system is used
Open the script in Script Editor
Save it as a "paquet de scripts" (I don't know the exact wording in English)
On the top/right of the script's window you will see an icon entitled "Contenu du paquet" (one more time, I don't know the exact wording in English)
Click on it to reveal a pane which will appear on the right edge of the window.
It contain a checkbox entitled "AppleScript/Bibliothèque Objective-C" (I assume that it's "AppleScript/Library Objective-C" in English)
Check it and resave the file.
Store it in one of the folder described in my late message.
After that, assuming that you named the library as mostRecentlyModifiedIemIn.scptd, you will be able to call it with :
Applescript:
use AppleScript version "2.3"
use theLib : script "mostRecentlyModifiedIemIn"
use scripting additions
use framework "Foundation"
set folderPosixPath to POSIX path of (choose folder)
set mostRecentlyModifiedIemIn to theLib's mostRecentlyModifiedIemIn:(folderPosixPath)
Yvan KOENIG running Yosemite 10.10.5 in French (VALLAURIS, France) lundi 17 août 2015 14:45:15
Offline
Hi Shane,
Thanks for the links.
I'll have a dabble when I get chance, looks interesting.
Last edited by TecNik (2015-08-19 06:30:19 am)
Offline
I needed a quicker way than Finder to sort a folder's files by modification date, which is why I found this thread. The folder has 400 files, and Finder varies, taking from about 6 to 11 seconds to sort it by mod date ("tell application 'Finder' to sort targetFolder by modification date"). Shane's handler on this page, which I don't understand, when modified for my needs (shown here), takes only about 3.5 seconds every time, to return a complete list of the 400 filenames. (I'm using a 2020 Macbook Air running Catalina). My way of doing this, as seen here, may be clumsy, but I don't know enough to do any better. If anyone needs a list of all filenames in a folder sorted by modification date by Shane's brilliant handler, this works better than using Finder. Thanks go to Shane.
--●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
--●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
--Shane's original coding (on this page) modified to return a list of filenames sorted in mod order. Cut and paste everything below this line into Script Editor to use.
--●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
global countOfFolderPosixFile --the only way I know to get this variable into Shane's handler (el7)
--●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
--Shane's coding
use AppleScript version "2.7"
use scripting additions
use framework "Foundation"
--●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
set folderPosixPath to POSIX path of (choose folder) --file path for Shane's handler below
set folderPosixFile to ((folderPosixPath as POSIX file) as string) --Mac file path for chosen folder (el7)
tell application "Finder" to set countOfFolderPosixFile to (count of (name of every file of (folderPosixFile as alias) as list)) as integer --# of files in chosen folder (el7)
--●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
--result of Shane's handler starts with "its". "its" seems both to invoke the handler and return its result, whereas in Applescript, with which I'm familiar, i've been doing the same thing the following way: "set myVariable to myHandler()" (el7 -- hope I'm accurate about this)
set sortedFileNames to its mostRecentlyModifiedIemIn:folderPosixPath
--●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
--returns a carriage-return-delimited string of the list sorted paths returned by Shane's handler (el7)
set AppleScript's text item delimiters to (character id 10)
set sortedFileNames to text items of sortedFileNames as string
--●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
set stripFilePaths to (character id 10) & ((folderPosixPath as POSIX file) as string) --creating delimiter for applescript string, which sortedFileNames is now (el7)
--●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
--strips out all, except the first, path strings in sortedFileNames string (el7)
set AppleScript's text item delimiters to stripFilePaths
set sortedFileNames to text items of sortedFileNames as list
--●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
set AppleScript's text item delimiters to ""
tell application "Finder" to set item 1 of sortedFileNames to name of (item 1 of sortedFileNames as alias) --strips out the first and only path string remaining in sortedFileNames (el7)
--●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
sortedFileNames --the MdGuffin, a list of file names of the chosen folder in descending modification date order, sorted by Shane's handler (el7)
--●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
--Shane's handler, mostly, with his notes, which are about the only things i understand (el7)
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
--●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
--build a list sorted by modification date by Shane's handler, using AppleScript lingo with a key line of Shane's (el7)
tell application "Finder"
set sortedFileNames to {} as list
repeat with i from 0 to countOfFolderPosixFile
((theInfoNSMutableArray's objectAtIndex:(i))'s valueForKey:(current application's NSURLPathKey)) as text -- extract path and convert to text--Shane's important line of code, with his "(0)'s" changed to my "(i)'s" in a repeat loop (el7)
set sortedFileNames to sortedFileNames & ((result as POSIX file) as string) as list
end repeat
return sortedFileNames --right here, all the heavy lifting is done (el7)
end tell
end mostRecentlyModifiedIemIn:
--end of modified coding
--●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
--●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
Model: MacBook Air 2020, OS 10.15.7
AppleScript: 2.7
Browser: Safari
Operating System: Other
Offline
For a list in modification order, use this code. And don't put it inside a Finder tell block.
Applescript:
use AppleScript version "2.3"
use scripting additions
use framework "Foundation"
set folderPosixPath to POSIX path of (choose folder)
its filesSortedByModDate:folderPosixPath
on filesSortedByModDate: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 oneURL in theURLs
(theInfoNSMutableArray's addObject:(oneURL'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 valueForKey:(current application's NSURLPathKey)) as list
end filesSortedByModDate:
Last edited by Shane Stanley (2021-02-22 07:21:41 pm)
Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com
Offline