Create a script to search a mounted volume???

So, I’m trying to create an "Application that can search a mounted Volume. I’m completely new to Applescripting (other than modifying other’s workflows at work occasionally) so please bear with me. What I would like the users to be able to do is drag their mounted volume they want searched onto the script, the script would take that path (say /Volumes/share) and pass that in as the first variable and essentially start the script. Then the script will have a pop-up asking for a filename. That filename will get passed in as the second variable. The script I would like it to run is a shell script that would look something like find $PATH -name ‘$FILENAME’ and the results would then display (I don’t care how they display, just that they are then able to see where that file is located).

The only part I’ve got so far is

do shell script "find $PATH -name '$FILENAME'"

So, how do I do the rest. :frowning:

If you can live with an Open-style folder picker instead of the drag-volume-to-script interface, then this might work for you:

(* Let the use pick a folder from which the search will start *)
set theFolder to choose folder with prompt "Select a mounted volume (or folder) to search:" -- There is no option to start from the "computer container" (where you find all the mounted volumes in Finder). You could start from POSIX file ("/Volumes" & ""), but that is not exactly the same (no Network entry, the startup volume is badged as a symlink/alias).
set theFolderPP to POSIX path of theFolder

(* Ask the user for the search filename pattern *)
set {text returned:theFilenamePattern} to display dialog "Enter a filename to search for (*, ?, and [] wildcards are available):" with title "Search " & theFolderPP default answer "filename"

(* remove trailing slash so find results do not have (harmless) double slash *)
if length of theFolderPP is greater than 1 and theFolderPP ends with "/" then set theFolderPP to text 1 through -2 of theFolderPP

(* Put together the find command and run it *)
set findCmd to "find " & quoted form of theFolderPP & " -iname " & quoted form of theFilenamePattern & " -print;true"
set findResults to do shell script findCmd

(* Display the results *)
-- choose from list is just a nice way of displaying the results, display dialog could be used, but long lines tend to be more difficult to read from display dialog
-- WARNING: splitting on paragraphs is not reliable in the face of filenames with embedded carraige returns and/or linefeeds
set theMatches to paragraphs of findResults
choose from list theMatches with prompt "Matching Items: " & length of theMatches with empty selection allowed

The choose folder dialog supports dropping a folder/volume from Finder into the dialog.
Your original idea of drag-volume-to-script is also doable, but the general semantics of dropping items on such a script were unclear to me so I took a different approach. Some of the questions for which I did not have answers: If multiple volumes/folders are dropped, should the script search every volume/folder dropped onto it or only the first? Should it prompt for a different search pattern for each volume/folder? What about files dropped onto the application? Should it include them in the searches, or should they just be silently ignored? If only files are dropped (no folders), should a warning or instructions be displayed (otherwise the app effectively does nothing in response to the drop)?

WOW! I didn’t expect it to be written for me :smiley: I think what you’ve provided me with is exactly what I’m looking for. I’ve got a couple questions though. What’s the difference between -iname and -name? (I can’t seem to find anything explaining the difference but can see it’s a valid option in the man pages for find). Second question is, what you’ve provided is exactly what I was hoping for but to take it one step farther, is it possible to allow the selection of the file(s) from the results to be shown in Finder?

I know that usually Spotlight or Finder can do all this searching for you, but due to our environment we have to use DAVE to mount some of our volumes and once DAVE is installed you can no longer search DAVE mounted volumes (this is confirmed by Thursby Software).

-iname is case insensitive: “.abc" will match entries named “fred.ABc”, “goff.Abc”, “sue.abc”, etc.
-name is case sensitive: "
.abc” would only match “sue.abc” from the above examples

Replacing the last line of the previous script with the following code will provide the “reveal selected items in Finder” functionality.

set chosenPaths to choose from list theMatches with prompt "Matching Items: " & length of theMatches with empty selection allowed and multiple selections allowed
if chosenPaths is not equal to false and length of chosenPaths is greater than 0 then
	set chosenFiles to {}
	repeat with f in chosenPaths
		try
			set end of chosenFiles to alias POSIX file (contents of f)
		end try
	end repeat
	if length of chosenFiles is greater than 0 then ¬
		tell application "Finder"
			activate
			reveal chosenFiles
		end tell
end if

If the results include files from many different folders and the user selects them all, Finder will open up a bunch of windows. This may be very annoying.

If you want to more properly handle files with newlines or carriage returns you should use -print0 instead of -print, add without altering line endings to the end of do shell script (after the shell script string argument) and use the following code in place of set theMatches to paragraphs of findResults.

to extractFind0Results(findResults)
	-- break up the null-delimited result of "find -print0"
	set {otid, text item delimiters} to {text item delimiters, {ASCII character 0}}
	try
		set foundPaths to text items of findResults
		set text item delimiters to otid
	on error m number n from o partial result r to t
		set text item delimiters to otid
		error m number n from o partial result r to t
	end try
	-- the output from "find -print0" always ends in a null, so drop the final, always empty entry
	if length of foundPaths is greater than 1 then
		set foundPaths to items 1 through -2 of foundPaths
	else
		set foundPaths to {}
	end if
	foundPaths
end extractFind0Results
set theMatches to exractFind0Results(findResults)

ah, just like grep -i :wink: I was thinking that but hadn’t tested it, guess I should have tested it :smiley:

Wow, perfect! I can tell I’m WAY behind on the Applescript. I need to go pickup a book or two and start creating some scripts. I appreciate your help.