Age old question, copy/rename from a list

Hey all! Trying to compile a multitude of scripts together to achieve this but have had little luck.

I need to copy a group of images, creating a new folder in the same location named something like ‘renamed images’, create a copy of the original images inside this new folder and rename them using a mix of a list and maintaining the prefix im and suffix of ‘_main’.

“im6035095_main.jpg” needs to become “imNewNumberFromList_main”

The prefix and suffix will never change so the script only needs to rename to always have ‘im’ and ‘_main’ wrapped around a new number pulled from a list. I can create the list of new numbers as a .csv or just normal .txt it matters not whatever is easiest for the scripting.

Here’s where I’m at and I’m sure it’s a royal mess. Feel free to build from it or point me in an all new direction. Currently it does copy images to the selected destination but does not rename properly. I would love to cut out the step of it asking for a destination though and just have it create a folder in the current location of the original images.

set sourceFolder to choose folder with prompt "Original Images"
set destFolder to choose folder with prompt "Rename Destination"
set NewNames to choose file with prompt ".TXT file of new names"
set theList to read NewNames using delimiter ","
tell application "Finder"
	set theItems to duplicate items of folder sourceFolder to folder destFolder with replacing
	repeat with curFile in theItems
		try
			set the name of curFile to ("im" & theList & "_main")
		on error
			display dialog "There was an error renaming files at the RIP" buttons {"OK"}
		end try
	end repeat
end tell

Hello.

It is untested!

set sourceFolder to choose folder with prompt "Original Images"
set destFolder to choose folder with prompt "Rename Destination" default location sourceFolder
set thePrefix to "im"
set theSuffix to "_main"
tell application "Finder"
	try
		set theItems to (duplicate items of folder sourceFolder to folder destFolder with replacing) as list
		repeat with curFile in theItems
			set originalName to the name of curFile
			set newName to thePrefix & (originalName) & theSuffix
			set the name of curFile to newName
		end repeat
	on error e
		tell me to display dialog "There was an error:" & e with title "Renaming Files" buttons {"OK"} with icon 2
	end try
end tell

Thanks McUsrII! This helped shed some light on my prefix/suffix issue, but this does not reference the .csv file for the new numbers that the files will be named to. I tried integrating it into my original script but still no luck.

It copies the files, but still seems to have an issue lining up the list of numbers and files, there are the same number of both. It names the first copied file to “main.jpg” and all subsequent files all seem to stay the same name as they were originally.

set sourceFolder to choose folder with prompt "Original Images"
set destFolder to choose folder with prompt "Rename Destination"
set NewNames to choose file with prompt ".TXT file of new names"
set theList to read NewNames using delimiter ","
set thePrefix to "zu"
set theSuffix to "_main"
tell application "Finder"
	set theItems to duplicate items of folder sourceFolder to folder destFolder with replacing
	repeat with curFile in theItems
		try
			set the name of curFile to thePrefix & theList & theSuffix
		on error
			display dialog "There was an error renaming files at the RIP" buttons {"OK"}
		end try
	end repeat
end tell

Hello.

It is still untested! But I think it should do what you want by now.

property lastLoc : missing value
if lastLoc is missing value then set lastLoc to path to desktop folder
tell application (path to frontmost application as text)
	set sourceFolder to choose folder with prompt "Original Images" default location lastLoc
	set lastLoc to sourceFolder
	set destFolder to choose folder with prompt "Rename Destination" default location sourceFolder
	set NewNames to choose file with prompt ".TXT file of new names" default location (path to desktop folder)
end tell
try
	set theList to read NewNames using delimiter ","
	set thePrefix to "im"
	set theSuffix to "_main"
	tell application "Finder"
		set theItems to (duplicate files of folder sourceFolder to folder destFolder with replacing) as alias list
		script o
			property l : theItems
			property m : theList
		end script
		set itemCount to (count theItems)
		if (count theList) ≥ itemCount then
			repeat with i from 1 to itemCount
				set newName to thePrefix & (item i of o's m) & theSuffix
				try
					set the name of item i of o's l to newName
				on error
					error "You have renamed files in this directory already!"
				end try
			end repeat
		else
			error "There were to few numbers for the items"
		end if
	end tell
	display alert "Proccessed: " & itemCount & " files."
on error e
	tell me to display dialog "There was an error:" & e with title "Renaming Files" buttons {"OK"} with icon 2
end try

For some reason it’s still having the same issue when it copies the files, they copy great now and stay in order without any odd renames, but none of them are being renamed to the new items in the list. It also always returns the error that there are too few numbers for the new items though I’ve triple checked that there are 60 images and 60 names. I thought maybe it was still an issue with the way my file was laid out but I’ve now tried as .csv, and tab delimited .txt and a few others without luck. Thanks for bearing with me!

Hello.

That was my fault, the script wanted to use items instead of files, which means it also wanted to move the folder to itself.

I have improved the script a little when it comes to speed, and it now saves the path to the last folder you were into, so that you have a vantage point between runs. I also set a default location for choosing the numbers file to the desktop, which you may change into something else should you want to. (Then

default location ("Your:Hfs:path:to:the:folder:which:contains:number:files:" as alias)

will do the trick).
I also added a notification, so that you can see the result of the operation immediately if it goes well.
You’ll find the updated version in post #4.

I’m getting a Syntax Error “Expected end of line, etc. but found identifier.” around the display notification but looking at it it seems correct.

Also I tried getting rid of the notification to try this and still the same issue for some reason, all items copied but no renaming happening at all, even testing the original images named something odd and the new copies do not get the prefix or suffix added. Will continue poking at it, it must be something simple in the way it’s trying to talk to the new list of names. Thank you for all of your help!!!

Hi,

Maybe the images take too long to copy. What if you use ‘ignoring application responses’?

gl,
kel

What happens if you put a long delay after the ‘duplicate’ command like ‘delay 2’?

Even with delay added it gives me the same issues, all copied but nothing renamed and the error that there are too few numbers for the items.

Hello.

Are you talking about the script in post #4? Reading back a little, did you open the script in your editor, or did you just copy it out?

I have edited the script in post #4 to not use display notification, as it has become reluctant with me as well, when run from the Script Menu.

Hello.

The version below, is now the original item in post #4, with display notificiation, I retested it, and it does indeed post the notification.

I have only tested the script with files of size 0 bytes, but that shouldn’t matter really. If you can’t rename the files, then I suspect the issue to be something else. I have added an error code in the script below, which would be nice to see the result of, when running the script on your machine.

use AppleScript version "2.3"
use scripting additions
property lastLoc : missing value
if lastLoc is missing value then set lastLoc to path to desktop folder
tell application (path to frontmost application as text)
	set sourceFolder to choose folder with prompt "Original Images" default location lastLoc
	set lastLoc to sourceFolder
	set destFolder to choose folder with prompt "Rename Destination" default location sourceFolder
	set NewNames to choose file with prompt ".TXT file of new names" default location (path to desktop folder)
end tell
try
	set theList to read NewNames using delimiter ","
	set thePrefix to "im"
	set theSuffix to "_main"
	tell application "Finder"
		set theItems to (duplicate files of folder sourceFolder to folder destFolder with replacing) as alias list
		script o
			property l : theItems
			property m : theList
		end script
		set itemCount to (count theItems)
		if (count theList) ≥ itemCount then
			repeat with i from 1 to itemCount
				set newName to thePrefix & (word 1 of item i of o's m) & theSuffix
				try
					set the name of item i of o's l to newName
				on error e number n
					error "You have renamed files in this directory already!" number n
				end try
			end repeat
		else
			error "There were to few numbers for the items" number 5000
		end if
	end tell
	tell me to display notification "Proccessed: " & itemCount & " files."
on error e number n
	tell me to display dialog "There was an error:" & e & "number: " & n with title "Renaming Files" buttons {"OK"} with icon 2
end try

Thanks! That has fixed my syntax error, but still receiving the error of too few numbers for the items and nothing is renamed. I’ve tried making the list of items greater than that of the files it renames without luck.

Hello.

My list looks like this:

Do you have comma separated values in your list?

Here’s my list

I changed the formatting a bit of it to match yours exactly but still getting the pop up of ‘You have renamed files in this directory already!’

Hello

Delete the contents of your destination directory, and try again.

If you would like to, I think you can set the delimiter to return in the read statement, so that you have the lines on separate lines, and if that doesn’t work, you can set the delimiter to linefeed.

I’ll update the script in post #12 as soon as I have posted this post, with some robustness for whitespace around the numbers. :slight_smile:

McUsrII You are the most patient person on earth… still no luck. Do you think loading the older version of applescript 2.3 would change the issue for the script in #12? I tried creating all the files in a new location just to make sure it wasn’t hanging up on something strange but still no luck. It’s a completely empty folder that I’m copying them to. I’ve tried both an excel document saved as a .csv, and also a .txt file :frowning:

Hello.

The file with the numbers, must be a pure text file, like you get in TextEdit when it on the format window says convert to rich text, if it says convert to pure text or whatever for the keyboard short cut command shift t, then press that!

Keep the commas for now, and try that, if that doesn’t work, then please paste in your text file here, exactly as you copied it from the file.

I find it strange that you don’t experience any error messages. :confused:

For the record AppleScript Version 2.3 is the latest version, it is used when you have AppleScript Editor version 2.6 and uses Mavericks.

Do you use Mavericks?

SUCCESSSSSSSSSSS

The rich text vs. pure text was exactly the problem… THANK YOU for all of your help and patience with this one!

Hello.

I am glad it works for you. I have a new version for you if you are ready for step 2:

I have played with the script in the mean time, I have added logic, for the situations, where there exists a file named with an identical number already.

Should it happen, then you are asked to replace it (Yes), or all (Yes to All), (so that you won’t be asked again), and the script merly removes any files that already exists with a conflicting name in the destination folder.

If you answer “No” to the dialog, then you are asked if you want to skip all conflicts, the first time around.
If you answer Yes to that, then all the files that can’t be renamed, because it already exists a file with that name in the desitination folder will be skipped. If you answer “No”, then you will be asked the same question on a per file basis.

When renameing of a file in the destination folder is to be skipped, then the default behaviour is to delete the file that has been copied into the folder to be renamed there.

Setting the property keepConflicts to true at the top of the script lets the source of the name conflicts be in the destination folder with their original names.

I hope you’ll try it out. :slight_smile:

use AppleScript version "2.3"
use scripting additions
property keepConflicts : false
property scriptTitle : "Duplicate and Rename in DestFolder"
property lastLoc : missing value
if lastLoc is missing value then set lastLoc to path to desktop folder
tell application (path to frontmost application as text)
	set sourceFolder to choose folder with prompt "Original Images" default location lastLoc
	set lastLoc to sourceFolder
	set destFolder to choose folder with prompt "Rename Destination" default location sourceFolder
	set NewNames to choose file with prompt ".TXT file of new names" default location (path to desktop folder)
end tell
duplicateAndRenumber(sourceFolder, destFolder, NewNames)

on duplicateAndRenumber(sourceFolder, destFolder, NewNames)
	set {overWriteAll, skipAll, haveAsked, movedCount} to {false, false, false, 0}
	try
		set thetext to read NewNames using delimiter ","
		set theList to cleanseList for (flattenTable for (explode from thetext by ","))
		set thePrefix to "im"
		set theSuffix to "_main"
		tell application "Finder"
			set theItems to (duplicate files of folder sourceFolder to folder destFolder with replacing) as alias list
			script o
				property l : theItems
				property m : theList
			end script
			set itemCount to (count theItems)
			if (count theList) ≥ itemCount then
				repeat with i from 1 to itemCount
					set newName to thePrefix & (word 1 of item i of o's m) & theSuffix
					try
						
						if exists file newName of folder destFolder then
							if not overWriteAll and not skipAll then
								tell me to set btn to button returned of (display dialog ¬
									"You have renamed files in this directory already" & return & "The file: " & newName & " exists" & return & "Proceed anyway?" with title my scriptTitle buttons {"No", "Yes to All", "Yes"} with icon 2 default button 3)
								if btn = "Yes" or btn = "Yes to All" then
									try
										move file newName of folder destFolder to trash
										set the name of item i of o's l to newName
										set movedCount to movedCount + 1
									on error
										error "An error occured during overwrite of file " & newName
									end try
									if btn = "Yes to All" then set overWriteAll to true
								else if btn = "No" and not haveAsked then -- button = No 
									tell me to set skipbtn to button returned of (display dialog ¬
										"Do you want to skip all files that already exists  in dest folder with a new file name?" with title my scriptTitle buttons {"No", "Yes"} with icon 2 default button 2)
									if skipbtn = "Yes" then set skipAll to true
									set haveAsked to true
									if not my keepConflicts then
										move item i of o's l to trash
									end if
								end if
							else if overWriteAll then
								try
									move file newName of folder destFolder to trash
									set the name of item i of o's l to newName
									set movedCount to movedCount + 1
								on error
									error "An error occured during overwrite of file " & newName
								end try
							else if skipAll then
								if not my keepConflicts then
									move item i of o's l to trash
								end if
							end if
						else
							set the name of item i of o's l to newName
							set movedCount to movedCount + 1
						end if
					end try
				end repeat
			else
				error "There were to few numbers for the items"
			end if
		end tell
		tell me to display notification "Duplicated and Renamed " & movedCount & "  out of " & itemCount & " Files." subtitle "Move and Rename"
	on error e
		tell me to display dialog "There was an error:" & e with title "Renaming Files" buttons {"OK"} with icon 2
	end try
end duplicateAndRenumber

on compactList for aList
	-- removes any empty list items
	set b to aList
	script o
		property l : aList
	end script
	repeat with i from 1 to (count aList)
		if item i of o's l = "" then set item i of o's l to missing value
	end repeat
	return o's l's text
end compactList

on flattenTable for aTable
	tell (a reference to text item delimiters)
		set {tids, contents} to {contents, return}
		set tmpTxt to aTable as text
		set aList to text items of tmpTxt
		set contents to tids
	end tell
	return aList
end flattenTable

on explode from theData by aDelim
	--takes  an initial chunck of text, turns it into paragraphs, and then turns 
	-- the paragraphs into lists with items. Any leading/trailing single 
	-- whitespace  around the list separator is removed with it.
	script o
		property theContents : theData
	end script
	if class of theData is list then
		-- we have been broken into paragraphs and must create
		-- a list of list for each paragraph.
		repeat with i from 1 to (length of o's theContents)
			set item i of o's theContents to explode from item i of o's theContents by aDelim
		end repeat
	else if (offset of linefeed in theData) > 0 ¬
		or (offset of return in theData) > 0 then
		-- We got an initial chunk of text we'll turn into paragraphs
		tell (a reference to text item delimiters)
			local tids
			set {tids, contents} to {contents, {linefeed, return}}
			set o's theContents to text items of o's theContents
			set contents to tids
		end tell
		-- And pass it onto ourself for processing each paragraph.
		set o's theContents to explode from o's theContents by aDelim
	else
		-- We must turn a paragraph into a list of ists.
		tell (a reference to text item delimiters)
			local tids
			set {tids, contents} to {contents, (space & aDelim)}
			-- removes any leading spaces from list separator.
			set o's theContents to text items of theData
			set contents to aDelim
			set o's theContents to o's theContents as text
			set contents to (aDelim & space)
			-- removes any trailing spaces from the list separator.
			set o's theContents to text items of theData
			set contents to aDelim
			set o's theContents to o's theContents as text
			-- breaks the string into a list by list separator.
			set o's theContents to text items of o's theContents
			set contents to tids
		end tell
	end if
	return o's theContents
end explode