Problem with file renaming

I’m sure this is a simple mistake but it has me stumped. The following script is intended to go through a list of strings and then check a folder full of files to see if any of the file names contain any of the strings. The script uses a renaming handler from an Apple-supplied script and will change the name of the first file. Then it hangs up because it looks like it’s looking for the first file again but can’t find it. Any help would be greatly appreciated. I’ve written dozens of scripts like this before. I’m not sure what I’m doing wrong here.


set New_List to {"16420", "15261", "15262", "15875", "15876", "16417", "16418", "16419", "15260", "16763", "16764", "16765"}
tell application "Finder" to set the source_folder to (folder of the front window) as alias
set the item_list to list folder source_folder without invisibles
set the item_count to the count of items in the item_list
set source_folder to source_folder as string

repeat with i from 1 to count of items in New_List
	set SKUChar_count to count of characters of (item i of New_List as text)
	repeat with j from 1 to item_count
		set this_item to item j of the item_list
		set this_item to (source_folder & this_item) as alias
		set this_info to info for this_item
		set the current_name to the name of this_info
		if current_name contains (item i of the New_List as text) then
			set G to number of characters in current_name
			set ext_char to characters (G - 2) thru G of current_name as text
			set base_name to characters 1 thru SKUChar_count of current_name as text
			set full_name to (base_name & "_F08." & ext_char)
			set_item_name(this_item, full_name)
		end if
	end repeat
end repeat

on set_item_name(this_item, new_item_name)
	tell application "Finder"
		--activate
		set the parent_container_path to (the container of this_item) as text
		if not (exists item (the parent_container_path & new_item_name)) then
			try
				set the name of this_item to new_item_name
			on error the error_message number the error_number
				if the error_number is -59 then
					set the error_message to "This name contains improper characters, such as a colon (:)."
				else --the suggested name is too long
					set the error_message to error_message -- "The name is more than 31 characters long."
				end if
				--beep
				tell me to display dialog the error_message default answer new_item_name buttons {"Cancel", "Skip", "OK"} default button 3
				copy the result as list to {new_item_name, button_pressed}
				if the button_pressed is "Skip" then return 0
				my set_item_name(this_item, new_item_name)
			end try
		else --the name already exists
			--beep
			tell me to display dialog "This name is already taken, please rename." default answer new_item_name buttons {"Cancel", "Skip", "OK"} default button 3
			copy the result as list to {new_item_name, button_pressed}
			if the button_pressed is "Skip" then return 0
			my set_item_name(this_item, new_item_name)
		end if
	end tell
end set_item_name




I think the problem stems from the aliased file in the nested repeat loop; aliased things remember where they live, and the second pass in the loop is probably looking at an outdated location. Try changing the repeat’s line 5 to “as string” and ““ a couple lines down ““ set the currentname to name of file this_info. Additionally, moving the main body of the script into a Finder block, rather than the single line construction, will help avoid having to return a clump of file information just to access the file name, which is having to be collected twice in the nested repeat; I’d nix that repeat, too.

A suggestion:


set theList to {"16420", "15261", "15262", "15875", "15876", "16417", "16418", "16419", "15260", "16763", "16764", "16765"}

tell application "Finder"
	set the source_folder to (folder of the front window) as string
	set the item_list to list folder source_folder without invisibles
	repeat with counterVar from 1 to count item_list
		set this_item to (source_folder & item counterVar of the item_list) as string
		set currentName to file this_item's name
		if currentName is in theList then
			set ext_char to characters -3 thru -1 of currentName as text
			set base_name to characters 1 thru -5 of currentName as text
			set fullName to (base_name & "_F08." & ext_char)
			my set_item_name(file this_item, fullName)
		end if
	end repeat
end tell

I was having trouble following your code. It seemed like there was a lot of stuff going on that didn’t need to be going on. Plus you were using the “info for” command which is deprecated so I rewrote the code. Here’s a working script…

set New_List to {"16420", "15261", "15262", "15875", "15876", "16417", "16418", "16419", "15260", "16763", "16764", "16765"}
set newListCount to count of New_List

tell application "Finder"
	set source_folder to folder of the front window
	set theFiles to every file of source_folder
end tell

repeat with i from 1 to count of theFiles
	set thisFile to item i of theFiles
	tell application "Finder" to set thisFileName to name of thisFile
	repeat with j from 1 to newListCount
		if thisFileName contains item j of New_List then
			tell application "Finder" to set thisFileExt to name extension of thisFile
			set thisFileBaseName to text 1 thru -((count of thisFileExt) + 2) of thisFileName
			set newname to thisFileBaseName & "_F08." & thisFileExt
			set_item_name(thisFile, newname)
			exit repeat
		end if
	end repeat
end repeat



(*===================== SUBROUTINES ======================*)
on set_item_name(this_item, new_item_name)
	set this_item to this_item as Unicode text
	tell application "Finder"
		set parent_container_path to (container of item this_item) as text
		if not (exists item (parent_container_path & new_item_name)) then
			try
				set the name of item this_item to new_item_name
			on error the error_message number the error_number
				if the error_number is -59 then
					set the error_message to "This name contains improper characters, such as a colon (:)."
				else --the suggested name is too long
					set the error_message to error_message -- "The name is more than 31 characters long."
				end if
				tell me to display dialog the error_message default answer new_item_name buttons {"Cancel", "Skip", "OK"} default button 3
				copy the result as list to {new_item_name, button_pressed}
				if the button_pressed is "Skip" then return 0
				my set_item_name(this_item, new_item_name)
			end try
		else --the name already exists
			tell me to display dialog "This name is already taken, please rename." default answer new_item_name buttons {"Cancel", "Skip", "OK"} default button 3
			copy the result as list to {new_item_name, button_pressed}
			if the button_pressed is "Skip" then return 0
			my set_item_name(this_item, new_item_name)
		end if
	end tell
end set_item_name

Brilliant. So simple. I was kind of flailing around. I think my original problem was using the alias (I never really know when to refer to a file and when to refer to a file as alias) and nesting the “repeat with files” inside the “repeat with the strings” loop. That kept failing so I began to get more and more elaborate in trying to refer to the files more clearly.

I like the way you get most of the Finder action out of the way at the beginning and load the list of files in and then use a single line with:
tell application “Finder” to set thisFileName to name of thisFile

I didn’t realize you could do that without writing a complete tell block.

Also, why do you use “text” instead of “character” to get the characters that make up the base of the file name? Is “text” dependent on what the TID is set to or will it always just refer to characters?

Thanks again.

I understand how that happens. Something doesn’t work right and your script gets more and more complicated trying to fix the problem. I get confused between using the alias, file reference, and text string of a path too. In general I find it easier for myself to just get a path, then change it to a string, and then in all my commands I just put the word file (or folder) before the string path. That way I always know what form I have and I find it easier to work with. But of course I don’t always do it that way as evidenced in my script.

Note the following applescript. When you use the word characters you get the individual characters returned to you in list format. When you use the word text the result is returned as a string. So when you want a string result use text, and when you want a list result use characters.

set aWord to "this word"
set theChars to characters 2 thru 7 of aWord
--> result: {"h", "i", "s", " ", "w", "o"}

set theText to text 2 thru 7 of aWord
--> result: "his wo"