Saturday, February 27, 2021

#1 2021-01-01 10:56:04 am

peavine
Member
From:: Prescott, Arizona
Registered: 2018-09-04
Posts: 788

Get and sort files in a folder

It's commonplace that I have to obtain files with a particular extension from one folder. I don't recall where but I found the script included below. With one exception it does what I want, but I wondered if there might be any improvements:

Applescript:

on getFiles(sourceFolder, fileExtensions) -- sourceFolder is POSIX path and fileExtensions is list of file extensions
   set fileManager to current application's NSFileManager's defaultManager()
   set theFolder to current application's |NSURL|'s fileURLWithPath:sourceFolder
   set folderContents to fileManager's contentsOfDirectoryAtURL:theFolder includingPropertiesForKeys:{} options:(current application's NSDirectoryEnumerationSkipsHiddenFiles) |error|:(missing value)
   set theFiles to current application's NSPredicate's predicateWithFormat_("pathExtension.lowercaseString IN %@", fileExtensions)
   set theFiles to folderContents's filteredArrayUsingPredicate:theFiles
   return theFiles as list
end getFiles

I need the returned list to be sorted by name in ascending order. I added a sort routine to the script but received an unrecognized-selector error, presumably because I cannot sort URL's in this manner. I looked at the NSArrray and NSURL documentation but didn't find a solution. How can I fix this or is there a better way.

Applescript:

on getFiles(sourceFolder, fileExtensions) -- sourceFolder is POSIX path and fileExtensions is list of file extensions
   set fileManager to current application's NSFileManager's defaultManager()
   set theFolder to current application's |NSURL|'s fileURLWithPath:sourceFolder
   set folderContents to fileManager's contentsOfDirectoryAtURL:theFolder includingPropertiesForKeys:{} options:(current application's NSDirectoryEnumerationSkipsHiddenFiles) |error|:(missing value)
   set theFiles to current application's NSPredicate's predicateWithFormat_("pathExtension.lowercaseString IN %@", fileExtensions)
   set theFiles to folderContents's filteredArrayUsingPredicate:theFiles
   set sortedFiles to (theFiles's sortedArrayUsingSelector:"compare:") -- error "-[NSURL compare:]: unrecognized selector sent to instance 0x600001825e00" number -10000
   return sortedFiles as list
end getFiles

Thanks for the help.

Last edited by peavine (2021-01-01 11:29:02 am)


2018 Mac mini - macOS Catalina

Offline

 

#2 2021-01-01 11:45:41 am

StefanK
Member
From:: St. Gallen, Switzerland
Registered: 2006-10-21
Posts: 11739
Website

Re: Get and sort files in a folder

NSURL instances cannot be sorted with the compare selector –  as stated by the error – because NSURL doesn't represent a single value like a string.

A solution is to use a NSSortDescriptor which sorts the array by the file name (in terms of NSURL the last path component)

Applescript:

on getFiles(sourceFolder, fileExtensions) -- sourceFolder is POSIX path and fileExtensions is list of file extensions
   set fileManager to current application's NSFileManager's defaultManager()
   set theFolder to current application's |NSURL|'s fileURLWithPath:sourceFolder
   set folderContents to fileManager's contentsOfDirectoryAtURL:theFolder includingPropertiesForKeys:{} options:(current application's NSDirectoryEnumerationSkipsHiddenFiles) |error|:(missing value)
   set theFiles to current application's NSPredicate's predicateWithFormat_("pathExtension.lowercaseString IN %@", fileExtensions)
   set theFiles to folderContents's filteredArrayUsingPredicate:theFiles
   set sortDescriptors to current application's NSArray's arrayWithObject:(current application's NSSortDescriptor's sortDescriptorWithKey:"lastPathComponent" ascending:true)
   set sortedFiles to (theFiles's sortedArrayUsingDescriptors:sortDescriptors)
   return sortedFiles as list
end getFiles


regards

Stefan

Offline

 

#3 2021-01-01 03:20:40 pm

peavine
Member
From:: Prescott, Arizona
Registered: 2018-09-04
Posts: 788

Re: Get and sort files in a folder

Thanks Stefan. That worked great.

FWIW, I ran some timing tests on the above script and the Finder equivalent. The test folder contained 20 PDF, 20 PNG, and 20 TXT files, and I set the scripts to get PDF files only. The first-run timing results were:

ASObjC - 0.028 seconds

Finder - 1.261 seconds

The ASObjC result is with the Foundation framework in memory, which would normally be the case if ASObjC is regularly used.

Last edited by peavine (2021-01-02 12:35:00 pm)


2018 Mac mini - macOS Catalina

Offline

 

#4 2021-02-02 12:14:11 pm

Fredrik71
Member
Registered: 2019-10-23
Posts: 630

Re: Get and sort files in a folder

Here is example of sorted files in a folder as POSIX path
This example the repeat loop start at 4 because in the folder it had 3 hidden files.

Be a ware it also count folders, so I guess other approach would consider if that matters.

Applescript:

use framework "Foundation"
use scripting additions

set thePath to POSIX path of (path to desktop pictures folder)
set {theResult, theError} to (current application's NSFileManager's defaultManager())'s contentsOfDirectoryAtPath:thePath |error|:(reference)
set theSort to (theResult's sortedArrayUsingSelector:"compare:") as list

set theList to {}
repeat with i from 4 to count theSort
   set theFilePath to thePath & item i of theSort
   copy theFilePath to end of theList
end repeat
return theList

Applescript:

use framework "Foundation"
use scripting additions

return my sortedFileListAtPath:(POSIX path of (path to desktop pictures folder))

on sortedFileListAtPath:thePath
   set {theResult, theError} to (current application's NSFileManager's defaultManager())'s contentsOfDirectoryAtPath:thePath |error|:(reference)
   set theSort to (theResult's sortedArrayUsingSelector:"compare:") as list
   set theList to {}
   repeat with i from 4 to count theSort
       set theFilePath to thePath & item i of theSort
       copy theFilePath to end of theList
   end repeat
   return theList
end sortedFileListAtPath:

Last edited by Fredrik71 (2021-02-02 12:33:13 pm)


The purpose to study someone else art is not to add, its to make less more.

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)