What is the fastest way to find files based on their extension? I’m writing a script that will ask the user to select a folder then it will look at the entire contents of the folder to find any files that end in “.session”. It a large script so I’ll just post the relevant section.
This approach is slow
set myFolder to ""
set newSessions to {}
choose folder with prompt "Select a folder containing Capture One session files"
set myFolder to result
tell application "Finder"
with timeout of 3600 seconds
set newSessions to every file of entire contents of myFolder whose name ends with ".session"
end timeout
end tell
return newSessions
This is fast because it is not looking in sub-folders
set myFolder to ""
set newSessions to {}
choose folder with prompt "Select a folder containing Capture One session files"
set myFolder to result
tell application "Finder"
with timeout of 3600 seconds
set newSessions to get files of folder myFolder whose name ends with ".session"
end timeout
end tell
return newSessions
Is there a way to script spotlight or use a shell command? After I gather these I use a handler to convert each to a URL to write back into a plist file.
set myFolder to (choose folder with prompt "Select a folder containing Capture One session files")
set newSessions to paragraphs of (do shell script "/usr/bin/find " & quoted form of POSIX path of myFolder & " -name \"*.session\"")
set myFolder to quoted form of POSIX path of (choose folder with prompt "Select a folder containing Capture One session files")
set newSessions to paragraphs of (do shell script "mdfind -onlyin " & myFolder & " 'kMDItemFSName = \"*.session\"'")
Wow! you guys are quick. Both methods are much faster then what I had, however my URL handler is expecting an alias. Any Advice?
set myFolder to quoted form of POSIX path of (choose folder with prompt "Select a folder containing Capture One session files")
tell application "Finder"
with timeout of 3600 seconds
set newSessions to paragraphs of (do shell script "mdfind -onlyin " & myFolder & " 'kMDItemFSName = \"*.session\"'")
end timeout
end tell
--return newSessions
set newSessionRefArray to {}
repeat with i in newSessions
set aItem to i
my getFileURL(aItem)
set end of newSessionRefArray to result
end repeat
return newSessionRefArray
--Handler to get URL of an alias
on getFileURL(aItem)
tell application "Finder" to set theFileURL to (URL of aItem)
return theFileURL
end getFileURL
I need to end up with a list of the .session files in URL form (file://…)
set myFolder to quoted form of POSIX path of (choose folder with prompt "Select a folder containing Capture One session files")
set newSessions to paragraphs of (do shell script "mdfind -onlyin " & myFolder & " 'kMDItemFSName = \"*.session\"'")
--return newSessions
set newSessionRefArray to {}
repeat with aItem in newSessions
tell application "Finder" to set end of newSessionRefArray to (URL of (POSIX file (contents of aItem) as alias))
end repeat
--Handler to get URL of an alias
on getFileURL(aItem)
tell application "Finder" to set theFileURL to (URL of ((POSIX file aItem) as alias))
return theFileURL
end getFileURL
@ Stefan - you were just waiting for it weren’t you
Isn’t that misleading? Each portion of the loop you are making a unique instance call to the Finder. Wouldn’t it be better to place the entire repeat inside a Tell “Finder” block so that you really are only making the call once?
set myFolder to quoted form of POSIX path of (choose folder with prompt "Select a folder containing Capture One session files")
set newSessions to paragraphs of (do shell script "mdfind -onlyin " & myFolder & " 'kMDItemFSName = \"*.session\"'")
--return newSessions
set newSessionRefArray to {}
tell application "Finder"
repeat with aItem in newSessions
set end of newSessionRefArray to (URL of (POSIX file (contents of aItem) as alias))
end repeat
end tell
Actually I meant the first tell block in mtorrance’s script
At compile time and at runtime it doesn’t matter whether you use a tell block around the repeat loop
or a single statement. The Event will be “connected” to the Finder anyway
One more question. Is it possible to use a sort command to sort the list of paths that are returned? More specifically I would like to sort the resulting list of URL’s by the filename (file://Volume/Folder/filename) or can it be sorted in the shell in the mdfind section? I didn’t see that option on the Man Pages.
You could pass the retrieved item paths to a Python script to sort them in alphabetically order (you need to adjust the path of the Python script according to your own environment):
set myFolder to quoted form of POSIX path of (choose folder with prompt "Select a folder containing Capture One session files")
set newSessions to paragraphs of (do shell script "mdfind -onlyin " & myFolder & " 'kMDItemFSName = \"*.session\"'")
set qtdstringpaths to ""
set countnewsessions to length of newSessions
repeat with i from 1 to countnewsessions
set cursession to item i of newSessions
if i is equal to countnewsessions then
set qtdstringpaths to qtdstringpaths & quoted form of cursession
else
set qtdstringpaths to qtdstringpaths & quoted form of cursession & ", "
end if
end repeat
set sortedpaths to paragraphs of (do shell script "/usr/bin/python /Users/martin/Desktop/sortitempaths.py " & qtdstringpaths)
Unfortunately AppleScript itself does not feature built-in sort routines
set myFolder to quoted form of POSIX path of (choose folder with prompt "Select a folder containing Capture One session files")
set newSessions to paragraphs of (do shell script "mdfind -onlyin " & myFolder & " 'kMDItemFSName = \"*.session\"'")
--return newSessions
set newSessionRefArray to {}
set newSessionNameArray to {}
set {ASTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, "/"}
tell application "Finder"
repeat with aItem in newSessions
set end of newSessionNameArray to last text item of aItem
set end of newSessionRefArray to (URL of (POSIX file (contents of aItem) as alias))
end repeat
end tell
set AppleScript's text item delimiters to ASTID
sort_items(newSessionNameArray, newSessionRefArray)
newSessionRefArray
to sort_items(|sortlist|, SecondList)
script L
property srt : |sortlist|
property sec : SecondList
end script
tell (count L's srt) to repeat with i from (it - 1) to 1 by -1
set s to (L's srt)'s item i
set r to (L's sec)'s item i
repeat with i from (i + 1) to it
tell (L's srt)'s item i to if s > it then
set (L's srt)'s item (i - 1) to it
set (L's sec)'s item (i - 1) to (L's sec)'s item i
else
set (L's srt)'s item (i - 1) to s
set (L's sec)'s item (i - 1) to r
exit repeat
end if
end repeat
if it is i and s > (L's srt)'s end then
set (L's srt)'s item it to s
set (L's sec)'s item it to r
end if
end repeat
end sort_items
Martin - Thanks for your input but this final script will be ran on various machines and I can’t control them having the python script although it probably could be included in the app bundle.
StefanK - Works like a charm! You boggle my mind with all the s’s and l’s
That dual-sort script is incredibly useful and easily extensible to more than two lists. It’s been kicking around the bbs for many years now but was originally written by Kai Edwards who was mad for the apostrophied form instead of “of” following the variable. By now it appears in many forms.
So just for the sake of completeness I am posting this slightly modified Python script that sorts the passed paths by file name
set myFolder to quoted form of POSIX path of (choose folder with prompt "Select a folder containing Capture One session files")
set newSessions to paragraphs of (do shell script "mdfind -onlyin " & myFolder & " 'kMDItemFSName = \"*.session\"'")
set qtdstringpaths to ""
set countnewsessions to length of newSessions
repeat with i from 1 to countnewsessions
set cursession to item i of newSessions
if i is equal to countnewsessions then
set qtdstringpaths to qtdstringpaths & quoted form of cursession
else
set qtdstringpaths to qtdstringpaths & quoted form of cursession & ", "
end if
end repeat
set sortedpaths to paragraphs of (do shell script "/usr/bin/python /Users/martin/Desktop/sortitempaths2.py " & qtdstringpaths)