Age old question, copy/rename from a list

This is amazing!!! I tried out a few scenarios with duplicates and love this.

One final curveball that could really make things crazy… Every once in a while (I am renaming images) there are multiple images of a single item. The main image has the _main and the secondary images are named as _alt_1, _alt_2 etc. I am going to try adding in an IF statement that would at least label these images in yellow and leave them in the folder while copying the rest. In a perfect world the script would read the original names and if an image has “_alt” in the name it would rename this image the same as the “_main” and keep them associated and then move on to the next image.

I.E.
im6035083_main.jpg
im6035086_main.jpg
im6035086_alt_1.jpg

im6035089_main.jpg

renames and maintains the _alt_1 and uses the same number as the main image without this new name needing to be in the .txt file twice?

I’ll look into that, and at the same time:

Would you feel more comfortable having the numbers with each number on a separate line? It just beats me to be an easier way of entering the number list.

I’ll test the solution thoroughly, so I shall post a solution before this time tomorrow at the latest. :slight_smile:

I’ve tried this with the numbers on separate lines but am not having luck as of yet. What delimiter would I use? I’ve tried “¬”. It seems that it definitely prefers the comma separated values, but perhaps there’s a delimiter I’m missing!

Don’t worry, I’ll change the script to handle that.

What I wonder is, how are the identical images named originally, before they get the _alt1,_alt2 extension, or do they have that extension already?

OR:

Do you want the “_alt” thing to happen upon a detection of a file already having that name, as an alternative to skip or overwrite.

I have to know how you think it should be incoroporated into your work flow. :slight_smile:

Personally I think it would be advantageous to have it as both an alternative in the dialog, (which maybe will turn into a list box with alternatives. However, say your images is stored in the original folder with the same name, and say a number after them, like file, file 1, file 2, file 3 and so on, then it is very easy to graft out all the file names for a batch which corresponds to one single number in your list. (I’ll sort the list by filenames, and any filenames with the same original names in the destination folder will be bluntly overwritten during the duplication phase).

Having it as an alterntative during the renaming after the duplication is very hard, and error prone, as I then have to know which “_alt number” the file is going to represent if not just the next higher, but I foresee this to be a messy and not so practical approach.

They already have the Extension and are designated as _main or _alt. Thank you again so very much :slight_smile:

Hello.

I updated the post while you answered.

Seeing your answer I have a follow up question:

I understand you to state that under this approach, the original files that there are more than one of will already have the suffix _main or _alt?

How about the files that only come in a quantity of one? Will all of those have the extension of _main already, or is that still a job for the script. (It’s no problem, I only have to figure out how it should work.) :slight_smile:

Sorry I completely missed a great portion of your response!

All files come with the designation as _main, _alt_1, _alt_2 … Those with a main image and alternate images have the same #. Below is a view of how the files are named before the renaming happens. Post rename all files should maintain the same format of prefix/suffix with a new number replacing the old. Those with multiple images as alts should repeat the same new number to keep them organized and associated with their _main file. The trick is that these numbers that repeat are not repeated in the .txt file of new numbers, the script must recognize which files have alts and repeat the same new number for as many alts as each file has and then move on to the next new number for the next file with a _main. Let me know if it’s still unclear :slight_smile: and as always, HUGE THANKS!

Example Original List:
im6476249_main.jpg
im6476252_main.jpg
im6476255_main.jpg
im6476255_alt_1.jpg
im6476255_alt_2.jpg

im6476258_main.jpg
im6476261_main.jpg
im6476261_alt_1.jpg

im6476264_main.jpg

Example Output List Post Script:
im1234567_main.jpg
im1234568_main.jpg
im1234569_main.jpg
im1234569_alt_1.jpg
im1234569_alt_2.jpg

im1234570_main.jpg
im1234571_main.jpg
im1234571_alt_1.jpg

im1234572_main.jpg

Hello.

I am a little bit belated today, I’ll come back to you asap.

Hello.

I have updated the script in post #20 for starters, so it now should act sanely on a list of numbers like below:

(Empty placeholders for numbers are ignored.) You can of course have a single number on a single line, without any commas. :slight_smile:

Thanks! In the mean time is there a way to update my applescript? After some searching and doing all normal updates on my computer I’ve hit a wall. The current script in #20 does not compile for me currently.

Version 2.5.1
AppleScript 2.2.4
OS X 10.8.5

Hello.

Just remove the use clauses at top, and change display notification into display alert, (you must remove the subtitle predicate and the subtitle itself too.)

The next version is very on its way. :slight_smile:

Hello.

Here is the new version. There is one thing I am unsure about, so you must check if the pictures keeps their jpg extension (in this case for me, keeps the name extension in general.)

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 as «class utf8»
		set theList to compactList for (flattenTable for (explode from thetext by ","))
		set thePrefix to "im"
		set theMainSuffix to "_main"
		set theAltSuffix to "_alt_"
		tell application "Finder"
			set theItems to (sort (duplicate files of folder sourceFolder to folder destFolder with replacing) by name) as alias list
			script o
				property l : theItems
				property newNum : theList
				property justNameTable : {}
			end script
			set renameCount to (count theItems)
			repeat 1 times
				local n
				set n to {}
				repeat with i from 1 to renameCount
					set end of n to name of item i of o's l
				end repeat
				set o's justNameTable to makeHelperTable of me for n
				-- We have to rearrange the ordering of stuff, as our semantics 
				-- doesn't coincide with lexical sorting.
				set i to 1
				repeat
					if (count item i of o's justNameTable) = 3 then
						local next
						set next to i + 1
						repeat
							if (count item next of o's justNameTable) = 3 then
								set next to next + 1
							else
								exit repeat
							end if
						end repeat
						-- the last shall be the first!
						local tmpNameHolder, tmpAliasHolder
						set {tmpNameHolder, tmpAliasHolder} to {item next of o's justNameTable, item next of o's l}
						set {item next of o's justNameTable, item next of o's l} to {item i of o's justNameTable, item i of o's l}
						set {item i of o's justNameTable, item i of o's l} to {tmpNameHolder, tmpAliasHolder}
						set i to next + 1
					else
						set i to i + 1
					end if
					if i > renameCount then exit repeat
				end repeat
				
				
			end repeat
			
			if (count theList) ≥ (count (uniqueList of me from o's justNameTable by 1)) then
				-- it is ok with superfluos numbers in the number list.
				-- trenger unique number count here.
				set newNumberIDX to 0
				repeat with i from 1 to renameCount
					
					if (count item i of o's justNameTable) = 2 then
						set newNumberIDX to newNumberIDX + 1
						set newName to thePrefix & (item newNumberIDX of o's newNum) & theMainSuffix & "." & item 2 of item i of o's justNameTable
					else
						set newName to thePrefix & (item newNumberIDX of o's newNum) & theAltSuffix & item 2 of item i of o's justNameTable & "." & item 3 of item i of o's justNameTable
					end if
					
					
					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 alert "Duplicated and Renamed " & movedCount & "  out of " & renameCount & " 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
end duplicateAndRenumber

on uniqueList from table by col
	script o
		property l : table
	end script
	set ul to {}
	repeat with i from 1 to (count table)
		tell item col of item i of o's l
			if it is not in ul then ¬
				set end of ul to it
		end tell
	end repeat
	return ul
end uniqueList


on makeHelperTable for aList
	-- takes filenames on the form "im<number>_main.jpg" or "im<number>_alt_<number>.jpg
	-- and forms it into a table for our convenience, when we are renaming a cluster
	-- of files that had the same number with the same number.
	script o
		property l : aList
		property m : {}
	end script
	tell (a reference to text item delimiters)
		set {tids, contents} to {contents, {"im", "_main", "_alt_", "."}}
		repeat with i from 1 to (count aList)
			set end of o's m to compactList of me for (text items of item i of o's l)
		end repeat
		set contents to tids
	end tell
	return o's m
end makeHelperTable

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
	-- turns a table into a single list of values
	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

I am blown away! This works absolutely perfectly other than it does not keep the .jpg extension currently. In the simpler versions I simply changed the suffix to _main.jpg and this worked great, but now that the _alt suffix is there and is adding the number as it counts the alts I’m in way over my head fixing this on my own!

:slight_smile: I was curious, now I know, and have added the .jpg extension to the name, the .jpg may of course be tiff, or img or whatever circumstantial file extension you use. The script is updated.

Works flawlessly! Thank you so much for all of your time and effort on this project. It’s immensely appreciated and will be a life saver!

:)Hopefully it saves you some time.

I’ll advice you to copy the link of this thread and put it on top of your scripts, so that you can find back to it later on, if you have other ideas. And it was a learning experience fo me, as I have been curious about how to implement the skip all stuff in AppleScript. :slight_smile:

Just come back if there are more to it, or if you adopt a different workflow. :slight_smile: