Search file server and get list of files containing search criteria

I’m trying to write a script to search an archive for all files containing certain characters and then create a file with the names of all the files found.

I’ve defined all the variables earlier. When I get to the “display dialog files_ as string” it breaks down and tells me that “files_” isn’t defined. BTW, that is in there because I was checking why I was getting that error on the following line.

What am I doing wrong or does any body else have an easier way to do this? Thanks all.

Here’s the chunk I’m having problems with:

tell application "Finder"
	set search_string to (ArtistName) as string
	with timeout of 300 seconds
		tell application "Finder"
			try
				set files_ to (files of ArchiveName whose name contains search_string) as alias list
			on error
				--set files_ to (first file of ArchiveName whose name contains search_string) as alias as list
			end try
			display dialog files_ as string
			my write_to_file(files_, files_, true)
		end tell
	end timeout
end tell

-- Write to file subroutine
on write_to_file(this_data, target_file, append_data)
	try
		set the target_file to the target_file as text
		set the open_target_file to open for access file target_file with write permission
		if append_data is false then set eof of the open_target_file to 0
		write this_data to the open_target_file starting at eof
		close access the open_target_file
		return true
	on error
		try
			close access file target_file
		end try
		return false
	end try
end write_to_file

I would comment out the “try” statement before you set the files_ variable. Chances are, you’re getting an error, but the try statement is hiding the error. That’s probably why files_ isn’t defined.

That’s my first thought anyway.
I usually comment out my “try” statements until I get the code working the way that I expect, then I uncomment them. They’re great for a working script, but it makes troubleshooting a script a lot harder.

Brian

When taking out the try statement and running the script, I get the following error: “Can’t get every file of "0207".” . (0207 is the vloume selected when testing.)

Do I need to re-word the search line somehow? I tried to to put volume in front of ArchiveName but that doesn’t help. Basically, this needs to search nested folders and get every file containing the search string.

Or am I missing something totally different on how this should be written?

Thanks,
Mike

Hi,

what is ArchiveName? It’s not defined in your script and it is the crucial point.
From the error message I guess, it’s just a (path) string, but it should be an alias or an file specifier

for example

set files_ to (files of folder ArchiveName whose name contains search_string) as alias list

or

set files_ to (files of alias ArchiveName whose name contains search_string) as alias list

ArchiveName is the variable name for the archive to mount. Here’s the complete (updated) script:


-- which archive to search?
set get_Archive to display dialog "Which archive do you want to search?" default answer "MMYY" buttons {"Cancel", "Continue"} default button "Continue"
set ArchiveName to text returned of get_Archive

-- Check for server, mount if needed
tell application "Finder"
	set diskList to list disks
	if diskList does not contain ArchiveName then
		try
			mount volume ArchiveName on server "02_Production_Server" as user name "mac01" with password ""
		on error
			display dialog "Could not mount the chosen archive. Please do it manually."
			return
		end try
	end if
end tell

-- which mac artist to search for?
set get_Artist to display dialog "Which mac artist do you want a report on?" default answer "12ABC" buttons {"Cancel", "Continue"} default button "Continue"
set MacArtist to text returned of get_Artist

tell application "Finder"
	make new file at desktop with properties {name:MacArtist & "Ads.txt"}
end tell

set AdListFile to "Macintosh HD:users:classpag:Desktop:" & MacArtist & "Ads.txt"
set eof of the (AdListFile as alias) to 0

tell application "Finder"
	set search_string to (MacArtist & ".indd") as string
	with timeout of 300 seconds
		tell application "Finder"
			--try
			set files_ to ((files of ArchiveName whose name) ends with search_string) as alias list
			--on error
			--set files_ to (files of ArchiveName whose name ends with search_string) as alias as list
			--end try
			if files_ as string = "" then
				display dialog search_string & " not found"
			else
				repeat with file_ in files_
					set Filename to name of file_
					set AdName to Filename & (ASCII character 13)
					my write_to_file(AdName, AdListFile, true)
				end repeat
			end if
		end tell
	end timeout
end tell

tell application "TextEdit"
	activate
	open AdListFile
end tell

on write_to_file(this_data, target_file, append_data)
	try
		set the target_file to the target_file as text
		set the open_target_file to open for access file target_file with write permission
		if append_data is false then set eof of the open_target_file to 0
		write this_data to the open_target_file starting at eof
		close access the open_target_file
		return true
	on error
		try
			close access file target_file
		end try
		return false
	end try
end write_to_file

I see, ArchiveName is even a disk, then use


.
set files_ to (files of disk ArchiveName whose name ends with search_string) as alias list
.

Note: MacArtist is already text, a coercion in the line

set search_string to (MacArtist & ".indd") as string

is useless, omit as string

Thanks, that eliminated getting the error. Now my problem is that it doesn’t find anything. I know there are files there because when I did the search manually (using the same data that I enter in the script), I found 243 files. The script doesn’t find anything.

Is there a logic error I’m not seeing? Or another error in the context of the code?

Mike

Two thoughts:

¢ The script searches only on the top level of the disk
¢ whose name ends. includes also the name extension of the file

I was wondering the same about only searching the top level. Not sure how to tell it to search all enclosed folders too.

I also tried changing the line to “contains” rather than “ends with”. I even dropped the .indd suffix once. Each time I got the same results. So I am leaning towards my first idea (only searching top level of disk). Isn’t there something with “contents” that might work? Doesn’t that include all enclosed folders as well?

I’m still trying to learn Applescript. I don’t do anything with it too often so it is taking me awhile to get it.

Mike

Well, I got it to work.

Here’s the line of code that I ended up using:


set files_ to ((every file of entire contents of disk ArchiveName whose name) ends with search_string) as alias list

It’s a little slow but it works.

Thanks for the help.

Mike

Hi Mike,

searching the entire contents on a server volume can take a long time,
here’s a suggestion, which uses the shell to find the files.
All files which names end with “indd” and contain MacArtist will be found

set ArchiveName to text returned of (display dialog "Which archive do you want to search?" default answer "MMYY" buttons {"Cancel", "Continue"} default button "Continue")

-- Check for server, mount if needed
if ArchiveName is not in (paragraphs of (do shell script "ls /Volumes")) then
	try
		mount volume ArchiveName on server "02_Production_Server" as user name "mac01" with password ""
	on error
		display dialog "Could not mount the chosen archive. Please do it manually."
		return
	end try
end if

-- which mac artist to search for?
set MacArtist to text returned of (display dialog "Which mac artist do you want a report on?" default answer "12ABC" buttons {"Cancel", "Continue"} default button "Continue")
set AdListFile to ((path to desktop as text) & MacArtist & "Ads.txt")
try
	do shell script "rm " & quoted form of POSIX path of AdListFile
end try

set files_ to paragraphs of (do shell script "find /Volumes/" & ArchiveName & " -type f  -name '*" & MacArtist & "*.indd' ! -name  '.*'")
if files_ is {} then
	display dialog MacArtist & " not found"
else
	set {TID, text item delimiters} to {text item delimiters, "/"}
	repeat with file_ in files_
		write_to_file((last text item of file_ & return), AdListFile, true)
	end repeat
	set text item delimiters to TID
end if

tell application "TextEdit"
	activate
	open AdListFile
end tell

on write_to_file(this_data, target_file, append_data)
	try
		set the target_file to the target_file as text
		set the open_target_file to open for access file target_file with write permission
		if append_data is false then set eof of the open_target_file to 0
		write this_data to the open_target_file starting at eof
		close access the open_target_file
		return true
	on error
		try
			close access file target_file
		end try
		return false
	end try
end write_to_file

I didn’t think you could run shell scripts on mounted servers. I thought you were limited to the local machine.

I’ll give your script a try Stefan.

Thanks for all the help.

Edit: Tried it.

Works great!