Recursive Directory Crawl

How do I get a list of files of a certain type which may be many levels deep within the directory heirarchy? Another way to describe this is that I want to duplicate the Automator action “Get Folder Contents” with “Repeat for each subfolder found” checked.

I found this script which resizes images, and I modified it to only grab tif files (I hope):

property openTypes : {"TIFF", "public.tiff"}

--Get the artwork file
set theFiles to choose file with prompt "Choose art file(s)" of type openTypes with multiple selections allowed without invisibles
runConversion(theFiles)

on runConversion(theItems)
	set saveFolder to choose folder with prompt "Save resized pictures where?" without multiple selections allowed and invisibles
	tell application "Image Events"
		launch
		set newHeight to 1200
		set newWidth to 0
		if (count items of theItems) is greater than 0 then
			repeat with anItem in theItems
				set imageFile to (open anItem)
				set theSize to dimensions of imageFile
				set width to item 1 of theSize
				set height to item 2 of theSize
				set ratio to (width / height)
				set newWidth to (ratio * newHeight) as integer
				if newHeight > newWidth then
					scale imageFile to size newHeight
				else
					scale imageFile to size newWidth
				end if
				save imageFile as JPEG in saveFolder
				close imageFile
			end repeat
		else
			display dialog "Nothing to convert."
		end if
	end tell
end runConversion

How would I also modify it to crawl through all the subdirectories (sometimes several layers deep)?

This is my first post, but I’ve been searching and browsing for a few days. Thanks to everyone that has made this site such a GREAT resource! I’m learning a lot. If I missed another post on this topic, please let me know so that I can improve my searching skills :slight_smile:

Model: MacBook Pro
AppleScript: 1.10.7
Browser: Firefox 2.0.0.3
Operating System: Mac OS X (10.4)

Hi mk

I think you need to be looking at something like this;

tell application "Finder"
	set t to every file of entire contents of (choose folder) whose file type is "Moov"
end tell

this will find all “.mov” files in a folder with sub folders.
you could change the file type to what you want!

entire contents will dig down thru as many folders there is, files just narrows it down and cuts out the folders.

Thanks pidge1,

Unfortunately, I am now getting the following error:

“The variable imageFile is not defined.”

with “imageFile” highlighted on this line:

set theSize to dimensions of imageFile

Here is the modified image converter with the code you suggested:

tell application "Finder"
	set theFiles to every file of entire contents of (choose folder) whose file type is "TIFF"
end tell

runConversion(theFiles)

on runConversion(theItems)
	set saveFolder to choose folder with prompt "Save resized pictures where?" without multiple selections allowed and invisibles
	tell application "Image Events"
		launch
		set maxSize to 1200
		if (count items of theItems) is greater than 0 then
			repeat with anItem in theItems
				set imageFile to (open anItem)
				set theSize to dimensions of imageFile
				set width to item 1 of theSize
				set height to item 2 of theSize
				if width > maxSize or height > maxSize then
					scale imageFile to size maxSize
				end if
				save imageFile as JPEG in saveFolder
				close imageFile
			end repeat
		else
			display dialog "Nothing to convert."
		end if
	end tell
end runConversion

Hi,

a way to do this is to use spotlight’s search engine.
mdfind returns the POSIX path of the found items, therefore the open line has also to be modified

set inputFolder to quoted form of POSIX path of (choose folder with prompt "Select folder which contains the art file(s)" without invisibles)
set theFiles to paragraphs of (do shell script "mdfind -onlyin " & inputFolder & " 'kMDItemContentType = \"public.tiff\"'")
runConversion(theFiles)

on runConversion(theItems)
	set saveFolder to choose folder with prompt "Save resized pictures where?" without multiple selections allowed and invisibles
	tell application "Image Events"
		launch
		set newHeight to 1200
		set newWidth to 0
		if (count items of theItems) is greater than 0 then
			repeat with anItem in theItems
				set imageFile to (open POSIX file (contents of anItem) as alias)
				set {width, height} to dimensions of imageFile
				set ratio to (width / height)
				set newWidth to (ratio * newHeight) as integer
				if newHeight > newWidth then
					scale imageFile to size newHeight
				else
					scale imageFile to size newWidth
				end if
				save imageFile as JPEG in saveFolder
				close imageFile
			end repeat
		else
			display dialog "Nothing to convert."
		end if
		quit
	end tell
end runConversion

Thanks StefanK!

My script is now working well. I can select an optical disk full of various directories, and it will pull all the TIFF’s. It resizes them if either edge is more than 1200 pixels, and moves them to a new directory in preparation for import into my database.

set inputFolder to quoted form of POSIX path of (choose folder with prompt "Select folder which contains the art file(s)" without invisibles)
set theFiles to paragraphs of (do shell script "mdfind -onlyin " & inputFolder & " 'kMDItemContentType = \"public.tiff\"'")
runConversion(theFiles)

on runConversion(theItems)
	set saveFolder to choose folder with prompt "Save resized pictures where?" without multiple selections allowed and invisibles
	tell application "Image Events"
		launch
		set maxSize to 1200
		if (count items of theItems) is greater than 0 then
			repeat with anItem in theItems
				set imageFile to (open POSIX file (contents of anItem) as alias)
				set {width, height} to dimensions of imageFile
				if width > maxSize or height > maxSize then
					scale imageFile to size maxSize
				end if
				save imageFile as JPEG in saveFolder
				close imageFile
			end repeat
		else
			display dialog "Nothing to convert."
		end if
		quit
	end tell
end runConversion

Note: I changed my script to use “find” instead of “mdfind”. For some reason, this is much more reliable for optical disks. Maybe mdfind is dependent on spotlight indexes which may not exist on removable media?


set theFiles to paragraphs of (do shell script "find " & inputFolder & " | grep .tif")
runConversion(theFiles)

You could have find check names directly:

choose folder with prompt "Choose the folder which contains the art file(s):" without invisibles
text 1 thru -2 of POSIX path of result -- Remove the trailing slash; `find` will add one itself

do shell script "/usr/bin/find " & quoted form of result & " -iname '*.tif' -or -iname '*.tiff'"

Side note: The trailing slash doesn’t matter to POSIX file, but it would need to be removed if you were going to pass those paths to other command line tools.

Thanks Bruce! That “text” line was JUST what I was looking for in another problem I’m working on (zero-size images). I’m not understanding all of it, but I’m learning a lot :slight_smile: