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?
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"