Easy to use yet versatile handler for finding folders by mdfind

Hello!

This handler returns folders from a given subtree that matches a name pattern. And for the record, I think StefanK came around with the first version of this handler.

I am tired of having a zillion handlers, that are basically the same with just some minor adjustments.

So I turned a handler for calling mdfind into something more useful, by adding a parameter for the return type, and a search predicate.

You can define the resultset, by specifiying first, last, all, or every match.

The search-predicate takes the values “begins with”, “ends with”, “contains” and “exact”.

There is no need to pass the foldername in quoted form, as it does that before calling mdfind.

Edit
if you enter an empy search term (“”) and sets the resultset to all, the search predicate to anything but exact, then you will receive a full list of the subfolders in the given subtree.

Edit
Coerces parameters to text, for the case that they are given from lists, or choose from list.


on findFolderOnly(resultType, searchPredicate, searchterm, directoryToSearchIn)
	-- © 2012 McUsr and put into public domain, you may not post this on its own, nor make it available in a public repository.
	-- please refer to this link: http://macscripter.net/viewtopic.php?pid=156879#p156879
	set {directoryToSearchIn, resultType, searchPredicate, searchterm} to {quoted form of directoryToSearchIn, resultType as text, searchPredicate as text, searchterm as text}
	if searchPredicate is "contains" then
		set searchterm to "\"*" & searchterm & "*\""
	else if searchPredicate is "begins with" then
		set searchterm to "\"" & searchterm & "*\""
	else if searchPredicate is "ends with" then
		set searchterm to "\"*" & searchterm & "\""
	else if searchPredicate is "exact" then
		set searchterm to "\"" & searchterm & "\""
	else
		error "The search predicate is misspelled!" number 4000
	end if
	if resultType = "first" or resultType = "last" or resultType = "all" or resultType = "every" then
		
		try
			local theResult
			set theResult to (do shell script "mdfind -onlyin " & directoryToSearchIn & " 'kMDItemFSName == " & searchterm & " && ( kMDItemContentType == \"public.folder\" || kMDItemFSSize == 0 )' ")
			if resultType = "first" then
				return first paragraph of theResult
			else if resultType = "last" then
				return last paragraph of theResult
			else if resultType = "every" or resultType = "all" then
				return theResult
			end if
		on error
			return {}
		end try
	else
		error "Wrong value for resulttype" number 4000
	end if
end findFolderOnly


Hello!

Here is an easy to use yet versatile handler for finding files in a folder by extensions. Mdfind gives too much back than just the mere folder, the find command can be tinkered to work faster, but ls is more than good enough when just looking for files in a folder. It returns a list of posix paths for the files found.

Thanks to DJ Bazzie Wazzie for finding such a clean way to build the pattern!

The pattern can be {“”} if you want all files, {“xls”,“xlm”,“applescript”,“scpt”} if you just want a selection.
The posix path to the folder should be quoted.

If there is no match, it should return an empty list, if you or I have done something wrong, it returns null!

Caveats Minor

As long as we know we are dealing with file extensions here, there is no practical importance to whether the dot is a literal dot or a regexp dot. if you insists of literal dots for saftey, then you can specify “\.html” as an extension.

So if you have filenames like mynothtmldocumenthtml it will be picked up, as a html file with “html” as an extension, unless you specify a literal dot in front of the html extension, like this: “\.html”




to listFilesByExt for aPosixFolder by extensionsList
	-- Building of RegExp pattern by DJ Bazzie Wazzie http://macscripter.net/edit.php?id=157205
	local oldTID, expr
	set {oldTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, "$|*."}
	set expr to quoted form of ("*." & extensionsList as string) & "$"
	set AppleScript's text item delimiters to oldTID
	try
		return paragraphs of (do shell script "ls " & aPosixFolder & " |  egrep " & expr)
	on error
		return null
	end try
end listFilesByExt

Hello. This is under construction

Here is one that seeks to do it all, files and folders, with some kind of syntax to it, it doesn’t handle searching of files by uti’s nor by default apps, or more esoteric searches, like by image sizes.

Should you make such a specialized fileList, don’t hesitate to upload it. :slight_smile:


# © McUsr and put in public Domain, you may not post this stand alone elsewhere, nor put it in a publically 
# accessible repository
# Please refer to this link: http://macscripter.net/edit.php?id=157655
-- fileList
-- =======

-- Example call:
---------------

--	set the flist to fileList({sTerm:".*", spath:theFolder, sType:"both", sPred:"re", sExt:{""}, sDepth:2, 
--      sWithInvisibles:true})


-- Properties of R the parameter for filelist of type record:
-- ==========================================================

-- sTerm: type string: MANDATORY
--------------------------------

-- The searchterm you are looking for, an empty search term will be interpreted as "*" (all files).
-- When it comes to specifying search terms the new type of regexp are allowed, so you can use
-- terms like "expenses second quarter 200\(4|5|6\).*" or "expenses second quarter [[.201.]]\(0|1|2\).*"
-- See man grep under the -E option and much better man re_format(7).
-- NOTE! To specify any with those kind of regexp you'll have to specify '.*' where you otherwise would have
-- specified '*'

-- sPath: type string: MANDATORY

-- The searchterm is a posix path or hfs path (hierchial file sysem path) to a directory that must exist,
--  it can end with "/" or ":" or not.


-- sType: type string
---------------------

-- What to search for: "file","folder" or "both". Optional, "file" is the default value.

-- sDepth: type integer
-----------------------

-- The depth of the search. Optional; defaults to 1.

-- 1 specifies that the search is  just to be performed in  the given directory, 
--  just a positive number gives the number of levels to search, or the levels up that number.
-- ( sed 'd' for større nivåer ) 
-- (-1) is the full subtree below the given directory, all levels.

-- sPred: type string
---------------------

-- The search predicate, specifies how the handler will interpret and use the searchTerm.
-- Optional; defaults to "regexp".

-- If there are no extension given, then the searchterm will specify the full pattern to search
-- for. Legal values:

--  "starts with":  Matches files/folders that starts with the search term.

--	 "ends with":    Matches files/folders that ends with the search term, it is not smart in the 
--                  sense that it will not match up to an extension, if none are given, if this is 
--						  what you want, then you'd specify an sExt of "". This is not default, as
--	                 some like the mother, other prefers the daughter! Example:
--                  if your specify ends with, and the filename is hackerne.ws and you search for ws,
--	                 without an extension, then you will miss this file.

--  "Contains":	     Matches files/folders that contains the searchterm somewhere (see Ends with.)

--  "Exact":         Exact match.

--	 "Regexp":		  The whole regexp is solely provided by the user, either with or without sExt, 
--                  but considering it if it is there. if you want all files, then don't specify 
--                  the sExt, set sPred to "regexp" and sTerm to "" or "*"

-- sExt: type list
------------------

-- The search extension, specifies which extension the file/folder list will be filtered against. 
-- It works in conjunction with sTerm, it takes a list of file extensions, *spelled fully out*.
-- Example: {"xls","xlsm","xlsx","xlsb"} is a valid list of extensions{"xls[bmx]"} is discouraged
-- but it works.
-- Optional parameter, default value {"*"} which means that any extension is allowed, but you must
-- specify and extension of {""} to make sure that nothing will be interpreted as extensions though. 
-- An empty extension is not allowed when more than one extension is given.

-- sWithInvisibles: type boolean
-------------------------

-- If invisible files are to be included or not. Optional, defaults to not include invisible files.

-- Returns a file list:
-- ====================

-- The file list will be returned in the format the search directory was given, posix path, or hfs.



to fileList(R)
	# preliminary checks of MANDATORY parameters
	local searchTerm, pathtype, tids, searchPath, hfsPattern, homePosixPath, DeepPath, searchType, searchPredicate, searchExtensions, searchWithInvisibles, searchDepth, findResult
	
	script common
		
		on initialParameterCheck()
			set tids to AppleScript's text item delimiters
			try
				set searchTerm to sTerm of R
			on error
				error "fileList: Mandatory parameter \"sTerm\" missing!"
			end try
			
			try
				set searchPath to spath of R
			on error
				error "fileList: Mandatory parameter \"sPath\" missing!"
			end try
		end initialParameterCheck
		
		on determinePathType()
			# We "fix" the given path to the folder we are using for our exploration!	
			if ":" is in searchPath then
				# We figure out what kind of path it is. Eventually converting it to posix.
				set pathtype to "hfs"
				if text -1 of searchPath is not ":" then set searchPath to searchPath & ":"
				set hfsPattern to searchPath # save for later!
				set AppleScript's text item delimiters to ":"
				set searchPath to text items of searchPath
				set AppleScript's text item delimiters to "/"
				set searchPath to "/" & text items 2 thru -1 of searchPath as text
				set AppleScript's text item delimiters to tids
			else if "/" is in searchPath or "~" is in searchPath then
				set pathtype to "posix"
				if text -1 of searchPath is not "/" then set searchPath to searchPath & "/"
			else
				error "fileList: The parameter \"sPath\" is invalid"
			end if
		end determinePathType
		
		on tildeExpand()
			# we perform tilde expansion:
			if "~" is in searchPath then
				set AppleScript's text item delimiters to "~"
				set searchPath to text items of searchPath
				set AppleScript's text item delimiters to homePosixPath
				set searchPath to searchPath as text
				set AppleScript's text item delimiters to tids
			end if
		end tildeExpand
		
		on assertSearchPath()
			# It is time to check if the path to the searchfolder indeed exists!
			# when you use this handler interactively then you'd use something like this:
			# choose folder. (posix path of theFolder as text for instance) **TODO documentation.
			try
				local probe
				set probe to POSIX file searchPath as alias
			on error
				error "fileList: the \"sPath\" does not exist!"
			end try
		end assertSearchPath
		
		on determineifPathIsDeep()
			if ((length of searchPath) - 1) ≤ length of homePosixPath then
				set DeepPath to true
			else
				set DeepPath to false
			end if
		end determineifPathIsDeep
		
		on setDefaultValuesForMissingParameters()
			set R to R & {sType:"file", sDepth:1, sPred:"regexp", sExt:{"*"}, sWithInvisibles:false}
		end setDefaultValuesForMissingParameters
		
		on setAndCheckParameterValues()
			set {searchType, searchPredicate, searchExtensions, searchWithInvisibles} to {sType of R, sPred of R, sExt of R, sWithInvisibles of R}
			
			# Prelimnary tests of user supplied parameters to the handler:
			if searchType is not in {"file", "folder", "both"} then error "fileList: typo in \"sType\"!"
			
			if searchPredicate is not in {"contains", "begins", "begins with", "ends", "ends with", "exact", "re", "regexp"} then error "fileList: typo in \"sPred\"!"
			
			if searchTerm = "" then set searchTerm to "*" # so we have something TODO maybe remove! Isn't common to both cases.
			
			if ("^" is in searchTerm or "$" is in searchTerm or "." is in searchTerm) and (searchPredicate is not "regexp" and searchPredicate is not "re") then error "fileList: illegal characters in \"sTerm\"!"
			
			if class of searchExtensions is not list then error "fileList: \"sExt\" must be a list!"
			set searchDepth to sDepth of R as number
			
		end setAndCheckParameterValues
	end script
	
	common's initialParameterCheck()
	common's determinePathType()
	set homePosixPath to text 1 thru -2 of POSIX path of (path to home folder)
	
	common's tildeExpand() # if we were given a posix path, error otherwise. hvis det startet med tilde men brukernavn etter?
	
	common's assertSearchPath()
	
	# if the path is deep then we'd better use Find than mdfind!
	# But we don't know if we can substitute Unix find for mdfind 
	# before we have seen the Depth parameter, depth > 3 ==> mdfind.
	common's determineifPathIsDeep()
	
	# Now that we have the essentials, we have to look over our options
	# and set defaults where parameters are amiss for starters!
	
	common's setDefaultValuesForMissingParameters()
	
	# All necessary parameters are now set, to default values if not specifed, it is time 
	# to analyze the query and "compile" the query.
	
	common's setAndCheckParameterValues()
	# we also analyze the search with regards to depth, and chooses the "right tool" for the job of creating
	# the filelist.
	
	if searchDepth ≤ 3 and DeepPath = true then # We leverage upon  Unix find for finding the files.
		# The finder commandline consists of several parts. (In order of appearance in the "compiled" commandline:)
		
		# head: 				the find command , and maybe -E for enhanced regexp, dependent on suffix
		
		# searchPath:		No dependencies
		
		# wayToSearch:		By name, or regexp, dependent on both sPredicate and sExt(ension(s))
		
		# baseNamePart: 	dependant on subclauses invisibles, and sExt
		
		# findSearchExt:	No depencies
		
		# searchPattern:	Depenent on baseNamePart and findSearchExt 
		
		# fileType dependant on searchType
		
		# redirection of stderr
		
		# we'll also throw an error and show an error message if the pattern or something wasn't valid.
		
		local fileType
		if searchType = "file" then
			set fileType to " -type f"
		else if searchType = "folder" then
			set fileType to " -type d"
		else # "both"
			set fileType to " -type f -o -type d"
		end if
		
		# compile the Base name.
		
		
		local invisibleClause
		if searchWithInvisibles is true then
			set invisibleClause to "'^\\.\\{0,1\\}" # testes!
		else
			set invisibleClause to "'^"
		end if
		
		local baseName, usesRegexp
		if searchWithInvisibles = true then
			set usesRegexp to true
		else
			set usesRegexp to false
		end if
		
		if searchPredicate is "contains" then
			set usesRegexp to true
			if searchTerm is not "*" then
				set baseName to invisibleClause & ".*" & searchTerm & ".*"
			else
				set baseName to invisibleClause & ".*"
			end if
			
		else if searchPredicate is "begins with" or searchPredicate is "begins" then
			set usesRegexp to true
			if searchTerm is not "*" then
				set baseName to invisibleClause & searchTerm & ".*"
			else
				set baseName to invisibleClause & ".*"
			end if
			
		else if searchPredicate is "ends with" or searchPredicate is "ends" then
			set usesRegexp to true
			if searchTerm is not "*" then
				set baseName to invisibleClause & ".*" & searchTerm
			else
				set baseName to invisibleClause & ".*"
			end if
		else if searchPredicate is "exact" then
			if searchTerm does not contain "*" then
				set baseName to invisibleClause & searchTerm
			else
				error "listFiles: * is not a valid specifier for an exact filename!"
			end if
		else if searchPredicate is "regexp" or searchPredicate is "re" then
			set usesRegexp to true
			if text 1 of searchTerm is "'" then set searchTerm to text 2 thru -1 of searchTerm
			if text -1 of searchTerm is "'" then set searchTerm to text 1 thru -2 of searchTerm
			if text 1 of searchTerm is "^" then set searchTerm to text 2 thru -1 of searchTerm
			if text -1 of searchTerm is "$" then set searchTerm to text 1 thru -2 of searchTerm
			# precautions.
			set baseName to invisibleClause & searchTerm
		end if
		# todo: check out hvordan går med quotes og name some name specifier.
		
		# todo: checks for file-ext here, up front. since we should really know this before we
		local singleExt, noExt, searchPattern
		set {noExt, searchPattern} to {false, ""}
		if length of searchExtensions > 1 then
			local firstExt
			set {singleExt, firstExt, usesRegexp} to {false, false, true}
			repeat with thisExt in searchExtensions
				if "." is in contents of thisExt then
					error "fileList: literal dots are not allowed in the \"sExt\"'s!"
				else if contents of thisExt = "" then
					error "fileList: empty extension in the \"sExt\" is not allowed when more than one!"
				else
					if firstExt = true then
						set firstExt to false
						set searchPattern to searchPattern & baseName & "\\." & thisExt
					else
						set searchPattern to searchPattern & "|" & baseName & "\\." & thisExt
					end if
				end if
				# todo : here	do we compile the searchExt
				
			end repeat
		else
			set singleExt to true
			# just one ext
			set theExt to item 1 of searchExtensions
			if theExt is not "" then
				if "." is in theExt then error "fileList: literal dots are not allowed in the \"sExt\"'s!"
				set searchPattern to baseName & "\\." & thisExt
			else
				set noExt to true
				set searchPattern to baseName
			end if
		end if
		set searchPattern to searchPattern & "'"
		
		
		# Assembling the command line:
		# We have to take the extensions into account here, We'll also have to change the 
		# simple names if we have to create from shell globs into regexps, and if there is
		# more than one, then we'll have to turn on -E for extended regexp's 
		
		if (usesRegexp = true and singleExt = false) then
			set headOfCommand to "find -E "
		else
			set headOfCommand to "find "
			# no need for enhanced regexp
		end if
		
		if searchPredicate = "exact" and singleExt = true then
			set wayToSearch to "-name "
		else
			set wayToSearch to " -iregex "
		end if
		# -maxdepth...
		
		local depthParameter
		
		set depthParameter to " -maxdepth " & searchDepth
		set findResult to (do shell script headOfCommand & (quoted form of searchPath) & wayToSearch & searchPattern & depthParameter & fileType & " 2>/dev/null | sed -n 's_//\\._/_p'")
		
		# END OF UNIX FIND VERSION
	else
		# we generate the parameters for the content type for the query
		
		local contentType
		if searchType = "file" then
			set contentType to " && ( kMDItemContentTypeTree == \"public.item\" && kMDItemContentType != \"public.folder\" )"
		else if searchType = "folder" then
			set contentType to " && ( kMDItemContentType == \"public.folder\" || kMDItemFSSize == 0 )"
		else # "both"
			set contentType to ""
		end if
		
		# The prevalent parameter down the road for generating the searchTerm is the searchExtension.
		local singleExt, holdPattern
		
		# precautions to only perform searches that may work.
		local holdPattern
		if searchPredicate is "contains" then
			if searchTerm is not "*" then
				set searchTerm to "\"*" & searchTerm & "*"
			else
				set searchTerm to "\"" & searchTerm
			end if
		else if searchPredicate is "begins with" or searchPredicate is "begins" then
			if searchTerm is not "*" then
				set searchTerm to "\"" & searchTerm & "*"
			else
				set searchTerm to "\"" & searchTerm
			end if
			
		else if searchPredicate is "ends with" or searchPredicate is "ends" then
			if searchTerm is not "*" then
				set searchTerm to "\"*" & searchTerm
			else
				set searchTerm to "\"" & searchTerm
			end if
		else if searchPredicate is "exact" then
			set searchTerm to "\"" & searchTerm
		else if searchPredicate is "regexp" or searchPredicate is "re" then
			set holdPattern to searchTerm
			set searchTerm to "\"*"
		end if
		# Invisibles. måten vi gjør dette på er at vi hvis vi har med invisibles, så legger vi dette til patternet. 
		# på en slik måte at vi får med begge deler.
		
		local itemNameSpec, singleExt # is where the string is stored to be fed to mdfind for the name pattern.
		
		if length of searchExtensions > 1 then
			
			set singleExt to false
			set itemNameSpec to " '( "
			repeat with thisExt in searchExtensions
				if "." is in contents of thisExt then
					error "fileList: literal dots are not allowed in the \"sExt\"'s!"
				else if contents of thisExt = "" then
					error "fileList: empty extension in the \"sExt\" is not allowed when more than one!"
				else
					set itemNameSpec to itemNameSpec & "kMDItemFSName == " & searchTerm & "." & thisExt & "\" || "
				end if
			end repeat
			set itemNameSpec to text 1 thru -4 of itemNameSpec & " ) "
		else
			set singleExt to true
			# just one ext
			set theExt to item 1 of searchExtensions
			if theExt is not "" then
				if "." is in theExt then error "fileList: literal dots are not allowed in the \"sExt\"'s!"
				
				set itemNameSpec to "'kMDItemFSName == " & searchTerm & "." & theExt & "\" "
			else
				set itemNameSpec to "'kMDItemFSName == " & searchTerm & "\" "
			end if
		end if
		
		# adds kdmiItem for invisible, so that invisible is included!
		local invisibleClause
		if searchWithInvisibles is true then
			set invisbleClause to " && ( kMDItemFSInvisible == '1' || kMDItemFSInvisible == '0' )'"
		else
			set invisibleClause to "'"
		end if
		
		# We are now done setting up the the different parts of the search we will feed mdfind with.
		local mdfindParameter, mdfindResult
		set mdfindParameter to itemNameSpec & contentType & invisbleClause
		
		#	try
		set mdfindResult to (do shell script "mdfind -onlyin " & (quoted form of searchPath) & " " & mdfindParameter without altering line endings)
		# 	end try
		if mdfindResult = "" then return null # No match ! 	
		# it is time for post processing in the cases that we sent with a reg exp.
		
		local hugeResult, temporaryFile, fref # if we get a really big result, we better store the result to disk, and work with it from a file.
		set bufferLen to length of mdfindResult
		set maxBufferLen to ((do shell script "getconf ARG_MAX") as number) - 10000
		if bufferLen > maxBufferLen then # 252144 Bytes, my fairly small free argspace - 1000 by getconf ARG_MAX
			set hugeResult to true
			try
				set temporaryFile to (do shell script "export TMPFILE=`mktemp /tmp/fileList.XXXXXX` && touch $TMPFILE && echo $TMPFILE")
			on error
				error "listFiles: I cant make a temporry file, quitting!"
			end try
			try
				set fref to (open for access POSIX file temporaryFile with write permission)
			on error e number n
				error "listFiles: I can't seem to open the temporary file : \"" & temporaryFile & "\" " & e & " " & n
			end try
			try
				write mdfindResult as «class utf8» to fref starting at 0
			on error e number n
				error "listFiles: I can't seem to write to  the temporary file : \"" & temporaryFile & "\" " & e & " " & n
			end try
			try
				close access fref
			on error
				close access fref
			end try
		else
			set hugeResult to false
		end if
		
		if searchPredicate is "regexp" or searchPredicate is "re" then
			if hugeResult is true then
				# it is really bes to work "infile" from now on, and it may even blow up in our face when we are done!
				try
					do shell script "sed -n -i '' '/" & holdPattern & "/p'  " & temporaryFile
					#					set mdfindResult to (do shell script "sed -n '/" & holdPattern & "/p' " & temporaryFile without altering line endings)
				on error e number n
					error "fileList: malformed regexp: " & e & " " & n
				end try
				
			else
				try
					set mdfindResult to (do shell script "sed -n '/" & holdPattern & "/p'<<<" & quoted form of mdfindResult without altering line endings)
				on error e number n
					error "fileList: malformed regexp: " & e & " " & n
				end try
			end if
		end if
		# posprocessing for mdfind unless the depth is -1, we must process it.
		if searchDepth is not -1 then
			# we'll have to escape the slashes in thefile name to make it work with sed.
			set AppleScript's text item delimiters to "/"
			set picketFence to text items of searchPath
			set AppleScript's text item delimiters to "\\/"
			set picketFence to picketFence as text
			set AppleScript's text item delimiters to tids
			
			#if we are searching for folders or both we'll first of all have to increase the depth, or adjust the patterns. [/]* could help on the end
			# won't get a hit on that when searches files anyways.
			
			if searchDepth is 1 then
				# huge result
				if hugeResult is true then
					set mdfindResult to (do shell script "sed  '/" & picketFence & "[^/]*[/][^/]*[/]*/ d' " & temporaryFile without altering line endings)
					
				else
					set mdfindResult to (do shell script "sed  '/" & picketFence & "[^/]*[/][^/]*[/]*/ d' <<<" & quoted form of mdfindResult without altering line endings)
				end if
			else
				set dirStr to "[^/]*[/]"
				# build the string for sed 
				repeat (searchDepth - 1) times
					set dirStr to dirStr & "[^/]*[/]"
				end repeat
				set dirStr to dirStr & "[^/]*[/]*/ d'"
				if hugeResult is true then
					set mdfindResult to (do shell script "sed '/" & picketFence & dirStr & " " & temporaryFile without altering line endings)
				else
					set mdfindResult to (do shell script "sed '/" & picketFence & dirStr & " <<<" & quoted form of mdfindResult without altering line endings)
				end if
			end if
			
			# this effectively removes any files or folders that are deeper in the tree structure than the specified level, keeping any others.
		else if searchDepth < -1 then
			error "fileList: illegal value for searchDepth, only -1 (for all levels) are allowed as a negative argument!"
		end if
		set findResult to mdfindResult
	end if
	
	# finally we must do some adjustments if we had hfspath's given initially.
	if pathtype = "hfs" then
		set AppleScript's text item delimiters to searchPath
		set findResult to text items of findResult
		set AppleScript's text item delimiters to hfsPattern
		set findResult to findResult as text
		set AppleScript's text item delimiters to tids
		set findResult to (do shell script "tr  [/] [:]  <<<" & quoted form of findResult without altering line endings)
		set findResult to (do shell script "sed '/^$/ d' <<<" & quoted form of findResult)
	end if
	return paragraphs of findResult
end fileList

For folks not familiar with the shell’s mdls and mdfind, I wrote a tutorial for them that explains how they work:

Using Spotlight in your AppleScripts

I have worked on this on and off for a while, I’ll post a message when it is thoroughly tested. :mad:

The whole idea is that you can forget everything about find and mdfind, and just use this handler. when you need to list something by wildcards and extensions. I have tried to use a combination of find and mdfind, to optimize it for speed. There are still some cases remaining when the output of mdfind is too large.

I’ll have it done during the evening!

Adam’s article is a very good read!

It should work in most cases now, as I have used the getconf ARG_MAX
to limit the size of the stream to the cases when the output of mdfind is less than that.

So it should work in most of the cases, but it isn’t tested methodically just yet.