Renaming Script

Hi everyone!!!

I’m new to the forums and to the world of scripting.

I have a folder on my desktop…in that folder are a bunch of subfolders and in those folders are JPG files. I want to rename all of those JPGs with a string and add a number so they are in sequential order. The sequence starts over for each folder.

I found this script that renames the JPGs in sequential order and starts over for each folder. For example, it renames:

Folder01
Image01.jpg to 01.jpg
Image02.jpg to 02.jpg
Etc, etc, etc.

Folder02
Pic01.jpg to 01.jpg
Pic02.jpg to 02.jpg
Etc, etc, etc.

I need this script to still do what it does, but also do this:

  1. Rename each JPG to Photo 01.jpg (string, then a space and then two or three digits in sequential order)
  2. Rename the extension to a lowercase .jpg

Appreciate any help!!!

   on run {input, parameters}

set oldFolder to ""

repeat with i in input

set f to my getFolder(i as text)

if f is oldFolder then

set counter to counter + 1

else

set counter to 1 -- reset the counter

set oldFolder to f

end if

tell application "Finder"

set nExt to name extension of i

if nExt is not "" then set nExt to "." & nExt

set name of i to (counter as text) & nExt

end tell

end repeat

return input

end run



on getFolder(t)

set {tid, text item delimiters} to {text item delimiters, ":"}

set f to text 1 thru text item -2 of t

set text item delimiters to tid

return f

end getFolder

You may try :

on run {input, parameters}
	
	set oldFolder to ""
	
	repeat with i in input
		
		set f to my getFolder(i as text)
		
		if f is oldFolder then
			
			set counter to counter + 1
			
		else
			
			set counter to 1 -- reset the counter
			
			set oldFolder to f
			
		end if
		
		tell application "Finder"
			
			set nExt to name extension of i
			
			if nExt is not "" then set nExt to "." & nExt
			set nExt to my UpperToLowercase(nExt) # ADDED
			
			set name of i to "Photo " & text -4 thru -2 of ((10000 + counter) as text) & nExt # EDITED
			
		end tell
		
	end repeat
	
	return input
	
end run



on getFolder(t)
	
	set {tid, text item delimiters} to {text item delimiters, ":"}
	
	set f to text 1 thru text item -2 of t
	
	set text item delimiters to tid
	
	return f
	
end getFolder

#===== ADDED

on UpperToLowercase(txt)
	set {oTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, ""}
	set lst to text items of txt
	repeat with i from 1 to count lst
		set achar to lst's item i
		if id of achar < 97 then set lst's item i to character id ((id of achar) + 32)
	end repeat
	set txt to lst as text
	set AppleScript's text item delimiters to oTIDs
	return txt
end UpperToLowercase

Yvan KOENIG (VALLAURIS, France) lundi 25 mai 2015 21:34:13

Errored. Says there’s already an item with that name.

Hi Cable. Welcome to MacScripter.

The script you posted doesn’t do quite what you suggest it does. Its input is a apparently list of file specifiers of some description and it renames the files in the order they come off the list, not necessarily with their original numbers or in the same sequence as those numbers. And unless the files from each folder are grouped together in the list, the counter for each folder will be reset to 1 every time the script comes back to it.

So it would help to know:

How are you getting the file list and what are you doing with it before passing it to the script?
Does this way of getting it suit your purposes? (I ask this because you’re using a found script, presumably written for someone else’s particular needs.)
Does each file name already contain the required number or do new number sequences need to be generated?
Related to the previous point, are the current numbers unique within each folder (eg. not both “Image01.jpg” and “Pic01.jpg” in the same folder)?
Does anything I’ve mentioned here explain why you may have got that particular error with Yvan’s version of the script?

Hi Nigel! And thanks for your response!!!

I’ll give all the details…I didn’t think some of this was pertinent and I didn’t want to confuse anyone.

I have a folder on my desktop called “Rename”. In that folder are a bunch of folders…those folders contain all .jpgs. They are usually all named with the same name and have a number, so they are in an order already and I’d like to preserve that order and rename each JPG to Pic 01.jpg, Pic 02.jpg, etc, etc. Then when it reaches the last image in the folder, it moves on to the next folder and renames those images to Pic 01.jpg, Pic 02.jpg, etc, etc. Essentially starting the renaming all over for each folder until it’s all done. I’d also like the rename the extension so it’s a lowercase .jpg in the process…just for neatness.

I have built and Automator workflow like this:

  1. Get Specified Finder Items - selecting the Rename folder on my desktop
  2. Get Folder Contents - repeat for each subfolder is checked
  3. Filter Finder Items - this is set up to filter out the folders (this keeps the folders from being renamed)
  4. Run Applescript - this is where that script I found is - as it is, it seems to work, but renames the images to just 01.jpg, 02.jpg, etc, etc. BUT I haven’t check to see if they’re in the same order after being renamed.

That’s pretty much it in a nutshell. Appreciate any help or insight.

I guess that I found what was wrong.

Replace the line :
set name of i to "Photo " & text -4 thru -2 of ((10000 + counter) as text) & nExt # EDITED
by
set name of i to "Photo " & text -4 thru -1 of ((10000 + counter) as text) & nExt # EDITED

The original code was creating the name “Photo 000.jpg” for the files supposed to be named :
Photo 0001.jpg
Photo 0002.jpg
Photo 0003.jpg
Photo 0004.jpg
Photo 0005.jpg
Photo 0006.jpg
Photo 0007.jpg
Photo 0008.jpg
Photo 0009.jpg

It would have done the same oddity for counter from 10 to 19 but it was unable to reach this case.

Yvan KOENIG (VALLAURIS, France) mercredi 27 mai 2015 13:00:34

Hi Cable.

Thanks for the information. I see Yvan’s now posted a correction to his script, but since I’ve been working on the one below, I may as well post it too. :wink:

I’m still not clear if the JPG names are supposed to keep their original numbers. For the moment, I’ve assumed that they are, because this saves having to generate the numbers in the script and having to think about the file order or folders. Other assumptions and understandings are shown in the comments:


-- Assumptions:
-- 'input' contains a list of file specifiers, aliases, Finder references, or HFS paths.
-- Any .JPG or .JPEG file referred to already has a number in its name which is to be kept.
-- This number is the last or only group of digits before the file's name extension.
-- Each number is unique amongst the JPG/JPEG names in any particular folder.

-- Items which are not JPG/JPEG files with numbers in their names are left alone.

on run {input}
	repeat with i in input
		set contents of i to i as alias -- Optional line to ensure the returned 'input' remains usable after the files are renamed.
		set filePath to i as text
		if ((filePath ends with ".jpg") or (filePath ends with ".jpeg")) then -- (These tests are case-insensitive.)
			-- If the target's a JPG/JPEG file, get the existing number (if any) from its name.
			set numberFromName to getNumberFromName(filePath)
			if (numberFromName is not missing value) then
				-- If a number's found, force a 2-digit version and rename the file as required.
				set numberFromName to text 2 thru 3 of ((100 + numberFromName) as text)
				tell application "Finder"
					set name of file filePath to "Photo " & numberFromName & ".jpg"
				end tell
			end if
		end if
	end repeat
	
	return input
end run

-- Extract a number from the file name in a given file path or return 'missing value' if no number.
-- (Called in this script after it's been established that the path is to a JPG/JPEG file.)
on getNumberFromName(filePath)
	set astid to AppleScript's text item delimiters
	-- Get the file name from the path
	set AppleScript's text item delimiters to ":"
	set fileName to text item -1 of filePath
	-- Cut the extension from the name.
	set AppleScript's text item delimiters to "."
	set n to text 1 thru text item -2 of filePath
	set AppleScript's text item delimiters to astid
	
	-- Now extract the last or only group of digits from what's left.
	
	set digits to "0123456789"
	try
		-- Locate the last digit. An error will occur if j reaches 0 (meaning no digits in the name).
		repeat with j from (count n) to 0 by -1
			if (character j of n is in digits) then exit repeat
		end repeat
		-- Locate the non-digit (if any) before the group.
		repeat with i from j - 1 to 1 by -1
			-- Output the digit group this way if a non-digit's found.
			if (character i of n is not in digits) then return text (i + 1) thru j of n
		end repeat
		-- Otherwise the group's at the beginning of the name. Output it this way.
		return text 1 thru j of n
	on error number -1700
		-- If the name doesn't contain any digits, display a message and return 'missing value'.
		display dialog "The name of file \"" & filePath & "\" doesn't contain a number." buttons {"Skip"} default button 1
		return missing value
	end try
end getNumberFromName

Wow!!! Thanks a bunch, Nigel and Yvan!!! Will try this at home tonight and let you know.

Let me clarify about the original file numbering…some folder have files like this:

Image01.jpg
Image02.jpg
Image06.jpg
Image12.jpg

I want to keep the order and then rename to Pic 01.jpg, Pic 02.jpg, etc, etc.

Hope that clears that up…sorry for leaving some gray areas. = )

Nigel,

Your script works great!!! Thank you so much!!!

It just keeps the numbers the same and I would like them to start at 01, then 02, 03, etc.

Is there a way to rename with 3 digits in cases where I have folders with 100 or more images? So the pics are Pic 001, Pic 002…Pic 100, Pic 101, etc.

Well. I’m glad you seem to be enthusiastic despite it not doing what you want. :wink:

Getting what you want requires a bit of a rethink. As a test, I’ve tried putting together your Automator workflow. I can’t get “Filter Finder Items” to pass anything at all, but without it, the “Run AppleScript” action receives aliases, which is good to know. In fact though, the three-line, commented-out ‘tell’ statement at the top of the script below can, if you prefer, be uncommented and used instead of the first three actions in the workflow.

The script contains its own sort (for my own peace of mind), generates its own number sequences, and uses two or three digits in the names, depending on whether there are less than 100 JPEGs in the folder or 100-or-more.

on run {input}
	-- If preferred, the next three lines can be uncommented and used instead of the preceding automator actions.
	-- tell application "Finder"
	-- 	set input to files of entire contents of folder "Rename" of desktop as alias list
	-- end tell
	
	-- Get the equivalent HFS paths for all the aliases in the input.
	set filePaths to getHFSPaths(input)
	-- For safety, ensure the paths are sorted by folder and then file name, considering numeric strings.
	considering numeric strings
		ShellSort(filePaths, 1, -1)
	end considering
	-- Rename JPG/JPEG files as required.
	renameJPGs(filePaths)
	
	return input -- Aliases still valid after files are renamed.
end run

-- Rename JPGs/JPEGs.
on renameJPGs(filePaths)
	script o
		property fp : filePaths
	end script
	
	-- Get a list of lists containing the numbers of {files, JPEGs} in the folders, in the same order as the folders occur in filePaths.
	set folderCounts to getFolderCounts(filePaths)
	-- Initialise various indices and counters.
	set f to 0 -- Index into folderCounts.
	set thisFolderCount to 0 -- The number of files in the current folder (item 1 of item f of folderCounts).
	set flleCounter to 1 -- File counter within the current folder.
	set jpgCounter to 1 -- Number to use in the next JPG/JPEG name.
	repeat with i from 1 to (count filePaths)
		-- Increment the file counter. If more than the number of files in the current folder, reset for the next folder.
		set flleCounter to flleCounter + 1
		if (flleCounter > thisFolderCount) then
			set f to f + 1
			set {thisFolderCount, thisJPGCount} to item f of folderCounts
			if (thisJPGCount < 100) then
				set d to -2 -- Use two digits in names when < 100 JPEGS in the folder.
			else
				set d to -3 -- Otherwise use three.
			end if
			set flleCounter to 1
			set jpgCounter to 1
		end if
		
		-- Get the next path from the list and rename the file if it's a JPG or JPEG.
		set thisPath to item i of o's fp
		if ((thisPath ends with ".jpg") or (thisPath ends with ".jpeg")) then
			tell application "Finder"
				set name of file thisPath to "Photo " & text d thru -1 of ((1000 + jpgCounter) as text) & ".jpg"
				set jpgCounter to jpgCounter + 1
			end tell
		end if
	end repeat
end renameJPGs

-- Given a list of ordered file paths, return a list of lists containing the numbers of {files, JPEGs} in the folders involved.
on getFolderCounts(filePaths)
	script o
		property fp : filePaths
	end script
	
	set folderCounts to {}
	set astid to AppleScript's text item delimiters
	set AppleScript's text item delimiters to ":"
	
	set thisPath to beginning of o's fp
	set currentFolder to text 1 thru text item -2 of thisPath
	set c to 1
	set j to ((thisPath ends with ".jpg") or (thisPath ends with ".jpeg")) as integer
	repeat with i from 2 to (count filePaths)
		set thisPath to item i of o's fp
		set thisFolder to text 1 thru text item -2 of thisPath
		if (thisFolder is currentFolder) then
			set c to c + 1
			if ((thisPath ends with ".jpg") or (thisPath ends with ".jpeg")) then set j to j + 1
		else
			set end of folderCounts to {c, j}
			set currentFolder to thisFolder
			set c to 1
			set j to ((thisPath ends with ".jpg") or (thisPath ends with ".jpeg")) as integer
		end if
	end repeat
	set end of folderCounts to {c, j}
	
	set AppleScript's text item delimiters to astid
	
	return folderCounts
end getFolderCounts

-- Return a list of equivalent HFS paths from a list of aliases.
on getHFSPaths(aliasList)
	set astid to AppleScript's text item delimiters
	set AppleScript's text item delimiters to linefeed
	set filePaths to paragraphs of (aliasList as text)
	set AppleScript's text item delimiters to astid
	
	return filePaths
end getHFSPaths

(* Shell sort, by Donald Shell, 1959.
AppleScript implementation: Nigel Garvey, 2010.
Parameters: (list, range index 1, range index 2)
*)
on ShellSort(theList, l, r)
	script o
		property lst : theList
	end script
	
	set listLen to (count theList)
	if (listLen > 1) then
		if (l < 0) then set l to listLen + l + 1
		if (r < 0) then set r to listLen + r + 1
		if (l > r) then set {l, r} to {r, l}
		
		set inc to (r - l + 1) div 2
		repeat while (inc > 0)
			repeat with j from (l + inc) to r
				set v to item j of o's lst
				repeat with i from (j - inc) to l by -inc
					tell item i of o's lst
						if (it > v) then
							set item (i + inc) of o's lst to it
						else
							set i to i + inc
							exit repeat
						end if
					end tell
				end repeat
				set item i of o's lst to v
			end repeat
			set inc to (inc / 2.2) as integer
		end repeat
	end if
	
	return -- nothing.
end ShellSort

Nigel…this script works GREAT!!!

THANK YOU SO MUCH!!! :D:D:D:D:D