Excuse the long answer…
There’s no simple built-in filtering. You can get information about NSURLs, such as whether they represent directories or aliases, but the values aren’t simple properties — they use methods that themselves require keys, so you can’t use shortcuts like valueForKey:
. You have to use use a repeat loop.
So first consider the simpler task, getting all the files — that is, everything that’s not a folder (like Finder’s files of
). There are two relevant keys: NSURLIsDirectoryKey
, which tells you if a URL is a directory (that is, a folder or a package), and NSURLIsPackageKey
, which tells you whether a URL is a package. So you typically check if a URL is a directory, and if it is, whether it’s a package. So something like this:
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
on listFilesIn:sourceFolder
set dirKey to current application's NSURLIsDirectoryKey
set packageKey to current application's NSURLIsPackageKey
set fileManager to current application's NSFileManager's defaultManager()
set aURL to current application's |NSURL|'s fileURLWithPath:sourceFolder
set theURLs to fileManager's contentsOfDirectoryAtURL:aURL includingPropertiesForKeys:{} options:(current application's NSDirectoryEnumerationSkipsHiddenFiles) |error|:(missing value)
set theResults to current application's NSMutableArray's array() -- to hold list
repeat with aURL in theURLs
set isFile to true
-- is it a directory?
set {theResult, theValue, theError} to (aURL's getResourceValue:(reference) forKey:dirKey |error|:(reference))
if theValue as boolean then
-- is it a package?
set {theResult, theValue, theError} to (aURL's getResourceValue:(reference) forKey:packageKey |error|:(reference))
if not theValue as boolean then
set isFile to false
end if
end if
if isFile then
(theResults's addObject:aURL)
end if
end repeat
return (theResults's valueForKey:"path") as list
end listFilesIn:
You can also get the value for several keys at once, in the form of a dictionary, then use a predicate to filter the items you want. Like this:
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
on listFilesIn:sourceFolder
set dirKey to current application's NSURLIsDirectoryKey
set packageKey to current application's NSURLIsPackageKey
set pathKey to current application's NSURLPathKey
set fileManager to current application's NSFileManager's defaultManager()
set aURL to current application's |NSURL|'s fileURLWithPath:sourceFolder
set reqKeys to current application's NSArray's arrayWithArray:{dirKey, packageKey, pathKey}
set theURLs to fileManager's contentsOfDirectoryAtURL:aURL includingPropertiesForKeys:reqKeys options:(current application's NSDirectoryEnumerationSkipsHiddenFiles) |error|:(missing value)
set theResults to current application's NSMutableArray's array() -- to hold result
repeat with aURL in theURLs
set {theValues, theError} to (aURL's resourceValuesForKeys:reqKeys |error|:(reference))
(theResults's addObject:theValues)
end repeat
set thePred to current application's NSPredicate's predicateWithFormat:"%K == NO OR %K == YES" argumentArray:{dirKey, packageKey}
theResults's filterUsingPredicate:thePred
return (theResults's valueForKey:pathKey) as list
end listFilesIn:
This is a little quicker, although not much.
Now to your question. You want the files, excluding aliases and symlinks. Two potentially relevant keys are NSURLIsSymbolicLinkKey
and NSURLIsAliasFileKey
. But there’s also NSURLIsRegularFileKey
, which defines “whether the resource is a regular file, as opposed to a directory or a symbolic link”. And once you start dealing with more keys, the second form is more efficient. So:
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
on listFilesNotAliasesOrSymlinksIn:sourceFolder
set regKey to current application's NSURLIsRegularFileKey
set packageKey to current application's NSURLIsPackageKey
set aliasKey to current application's NSURLIsAliasFileKey
set pathKey to current application's NSURLPathKey
set fileManager to current application's NSFileManager's defaultManager()
set aURL to current application's |NSURL|'s fileURLWithPath:sourceFolder
set reqKeys to current application's NSArray's arrayWithArray:{regKey, packageKey, aliasKey, pathKey}
set theURLs to fileManager's contentsOfDirectoryAtURL:aURL includingPropertiesForKeys:reqKeys options:(current application's NSDirectoryEnumerationSkipsHiddenFiles) |error|:(missing value)
set theResults to current application's NSMutableArray's array() -- to hold result
repeat with aURL in theURLs
set {theValues, theError} to (aURL's resourceValuesForKeys:reqKeys |error|:(reference))
(theResults's addObject:theValues)
end repeat
set thePred to current application's NSPredicate's predicateWithFormat:" (%K == YES AND %K == NO) OR %K == YES" argumentArray:{regKey, aliasKey, packageKey}
theResults's filterUsingPredicate:thePred
return (theResults's valueForKey:pathKey) as list
end listFilesNotAliasesOrSymlinksIn:
Edited as discussed below.