How does one generate a "grouped" directory contents as a list?

Is there an easy Applescript way to set a list variable to a sorted grouped list of filenames in a directory?

ie. {{filename1.ext, “image”}, {filename2.ext, “image”}, {filename3.ext, “movie”}, {filename4.ext, “movie”}, …}

The organization is visually similar to what one sees using “grouped” in the “view” menu of finder.

Well. You could perhaps compile this sort and save the script in /Users/yourname/Library/Script Libraries/ with the name “Custom Iterative Ternary Merge Sort.scpt”, then try this:

use sorter : script "Custom Iterative Ternary Merge Sort"
use scripting additions

set someFolder to (choose folder)

-- Get lists of the names and kinds of the all the files in the folder.
tell application "System Events" to set {fileNames, fileTypes} to {name, kind} of files of someFolder

-- Match the names and the kinds as {name, kind} lists, but not where names begin with ".".
set output to {}
repeat with i from 1 to (count fileNames)
	set thisName to item i of fileNames
	if (thisName does not start with ".") then set end of output to {item i of fileNames, item i of fileTypes}
end repeat

-- Set up a comparison script object for the sort.
-- List a should be sorted after list b if their last items are the same and a's first item > b's first item, or if a's last item > b's last item.
script onEndThenBeginning
	on isGreater(a, b)
		if (end of a = end of b) then
			return (beginning of a > beginning of b)
		else
			return (end of a > end of b)
		end if
	end isGreater
end script

-- Sort items 1 thru -1 of the list of lists in the prescribed manner.
tell sorter to sort(output, 1, -1, {comparer:onEndThenBeginning})

return output
--> {{"1 Audio Track.aac", "AAC Audio"}, {"2 Audio Track.aac", "AAC Audio"}, {"3 Audio Track.aac", "AAC Audio"}, {"4 Audio Track.aac", "AAC Audio"}, {"1 Audio Track.aiff", "AIFF-C audio"}, {"2 Audio Track.aiff", "AIFF-C audio"}, {"3 Audio Track.aiff", "AIFF-C audio"}, {"4 Audio Track.aiff", "AIFF-C audio"}}

Nigel;

Perhaps a silly question…

Being a newbie to AppleScript, I don’t know if the following is possible.

When one uses something like the following to get a list of the files in a directory, are they returned in the same order as they would have been displayed? If so, Could subsequent sorting of the list be avoided by somehow mimicking setting the “View” to “Use Groups” and “Group By” → “Kind”, when making the call?


-- Get all the files having a root filename, which is the same root filename as the ".meta" file, except the ".meta" file itself.

tell application "System Events"
	set theList to (name of files of alias (thePath) whose (name begins with theFilename & ".") and (name does not contain ".meta"))
end tell

Hi.

I don’t think so. Testing quickly here, the Finder tends to return disk items in name order and System Events in some other order, albeit more quickly. Changing the grouping view in the Finder window doesn’t change the order in which the items are returned to scripts.

The Finder does have have its own ‘sort’ command, which you may prefer if you don’t have a lot of files to process:

set someFolder to (choose folder)
tell application "Finder" to (sort files of someFolder by kind)

This returns a list of Finder references to the files, sorted by kind and by name within that, similarly to my script two posts up. You then have to get the name and kind from each one individually. So it’s OK for small numbers of files, but slower than my earlier script.

Very much tends, these days. I’m seeing them half sorted here. (10.14.2)

Thanks for the input fellows. Now I have a way of generating the sorted list.

Yes indeed. I was getting name-sorted results in my quick confirmatory tests yesterday, but it’s never been a good idea to assume that the Finder will return disk items in any particular order unless it’s explicitly told to do so. And some of us are cynical enough not even to trust that! :wink:

I enjoy questions like this, as they allow me to practice the stuff I use a lot. The following is my implementation of the suggestion contained in Nigel’s second post.


set selectedFolder to choose folder

set myFiles to {}

tell application "Finder"
	set sortedFiles to (sort files of selectedFolder by kind)
	repeat with aFile in sortedFiles
		set {fileName, fileType} to {name, kind} of aFile
		set the end of myFiles to {fileName, fileType}
	end repeat
end tell

get myFiles

Hi peavine.

That’s exactly what I had in mind. But in fact the Finder doesn’t see files whose name begins with “.”, so that check isn’t necessary. It was in my first script because System Events does see them.

Thanks Nigel; I have corrected the script to omit that check.

Thank you, both. As I don’t have many files that would pass the filtering I need to do, I think the quick and dirty version should work.

That depends on whether you have invisible files showing in Finder’s UI or not, though (toggled by command-shift-. in recent versions of the OS). So it’s probably best to leave the test in in this case.

Another reason why Finder scripting is so fraught…

Although it might be argued that someone who’s set their computer to show such items would want them in the script result too. :slight_smile: