Renaming Files Sequentially

I have been working on this script for a while. I have it working up to a point. It will process a set of signs, export them as pdf, and extract a pdf’s pages into separate files. I am trying to add a way to rename them to our naming convention but so far it keeps renaming them out of order. Can anyone tell me what I’m doing wrong?


--Processing and Prepping for print happens before all this.

--Javascript to extract pages of PDF
property JavaScript : "var re = /.*\\/|\\.pdf$/ig; var filename = this.path.replace(re,\"\"); try { for (var i = 0; i < this.numPages; i++) this.extractPages( { nStart: i, cPath: filename+\"_\" + (i+1) +\".pdf\" }); } catch (e) { console.println(\"Aborted: \"+e) }" as text

	set thisdoc to document 1 --this normally happens near the start, but since I skipped it...

		--------------------------------------------------------------------------------
		-------------------------------Process PDF ----------------------------------
		--------------------------------------------------------------------------------
		
		set exportPath to (choose folder) as string
		
		--export document as PDFs
		tell application id "com.adobe.InDesign"
			activate
			set myPDFexport to get the name of every PDF export preset
			set myPDFchoice to ("Caldera .125 Bleed No Conversion") as string
			repeat with thisdoc in (active document)
				set docName to get name of thisdoc
				tell thisdoc
					export format PDF type to exportPath & (characters 1 thru -6 of docName) & ".pdf" using myPDFchoice without showing options
				end tell
			end repeat
		end tell
		
		--extract pages of PDF to home folder
		tell application "Adobe Acrobat"
			activate
			do script JavaScript
			close document 1 saving no
		end tell
		
		--close Adobe Acrobat
		tell application "Adobe Acrobat" to quit
		
		tell application "Finder"
			set originalFile to exportPath & (characters 1 thru -6 of docName) & ".pdf"
			if exists originalFile then delete originalFile
		end tell
		
		tell application id "com.adobe.InDesign"
			activate
			close thisdoc saving no
		end tell
	end if
end tell

tell application "Finder"
	activate
	display dialog "Click to Rename" buttons {"OK"} default button 1
	if result = {button returned:"OK"} then
		--------------------------------------------------------------------------------
		-------------------------------Rename PDFs----------------------------------
		--------------------------------------------------------------------------------
		
		tell application "Finder" to set exportFiles to files of folder exportPath
		set count_er to 1
		repeat with i from 1 to count exportFiles
			tell application "Finder" to set name of item i of exportFiles to ((characters 1 thru -6 of docName as string) & (text -2 thru -1 of ("00" & (count_er as string))) & "." & "pdf")
			set count_er to count_er + 1
		end repeat
	end if
end tell

I figured out the problem. The files are originally name as such:
B_UHV_TS_1.pdf
B_UHV_TS_2.pdf
B_UHV_TS_3.pdf
B_UHV_TS_10.pdf
B_UHV_TS_23.pdf
B_UHV_TS_28.pdf

But they rename in this order:
B_UHV_TS_1.pdf
B_UHV_TS_10.pdf
B_UHV_TS_2.pdf
B_UHV_TS_23.pdf
B_UHV_TS_28.pdf
B_UHV_TS_3.pdf

I need to add a zero to the single digit files. Here’s the script I’m working on, but it won’t work and I can’t figure out why.


tell application "Finder"
	set exportFiles to files of folder exportPath
	set count_er to 1
	repeat with i from 1 to count exportFiles
		if name of item i contains "_1.pdf" then
			set insertionString to ("0")
			set after (character -5 of text of fileName) to insertionString
		else	
			tell application "Finder" to set name of item i of exportFiles to ((characters 1 thru -6 of docName as string) & (text -2 thru -1 of ("00" & (count_er as string))) & "." & "pdf")
			set count_er to count_er + 1
		end if
	end repeat
end tell

I’m not surprised that your code fails, it contain many errors.

(1) I was surprised by the use of “after” because my memory said that it can’t be used to insert a character in a string.
I decided to check with

set filename to "abcdefghijkl_1.pdf"
set insertionString to ("0")
set after (character -5 of text of filename) to insertionString

I was glad to see that my memory was not too bad when I got :
error “Il est impossible de régler after "1" à "0".” number -10006 from insertion point after “1”

The message underlined an other oddity too. You are trying to insert a “0” after the “1” when it would be logical to insert it before.
Correct code would be something like:

set filename to "abcdefghijkl_1.pdf"

set newName to text 1 thru -6 of filename & "0" & text -5 thru -1 of filename

(2) I commented other oddities directly in your code :

tell application "Finder"
	set exportFiles to files of folder exportPath
	set count_er to 1
	repeat with i from 1 to count exportFiles
		if name of item i contains "_1.pdf" then
			set insertionString to ("0")
			set after (character -5 of text of fileName) to insertionString # Here fileName is not defined
			# Worse, you try to modify a string, but don't ask the Finder to rename the file accordingly
		else
			# Why are you using tell Finder as you are already in a tell Finder  block ?
			tell application "Finder" to set name of item i of exportFiles to ((characters 1 thru -6 of docName as string) & (text -2 thru -1 of ("00" & (count_er as string))) & "." & "pdf") # Here docName is not defined
			set count_er to count_er + 1
		end if
	end repeat
end tell

All in all you may try :

tell application "Finder"
	set exportFiles to files of folder exportpath
	set count_er to 1
	repeat with i from 1 to count exportFiles
		set fileName to name of item i of exportFiles
		if fileName ends with "_1.pdf" then
			set newName to text 1 thru -6 of fileName & "0" & text -5 thru -1 of fileName
			set name of item i to newName
		else if fileName ends with ".pdf" then
			set newName to (text 1 thru -6 of fileName) & text -2 thru -1 of ((100 + count_er) as string) & ".pdf"
			set name of item i to newName
			set count_er to count_er + 1
		end if
	end repeat
end tell

As you may see I take care of possible files whose name wouldn’t end with .pdf.
It’s required on my system where invisibles are always make visible so the script would face at least “.DS_Store” or “.localized” or "Icon
"
To be honest, I didn’t tested it

Yvan KOENIG running Yosemite 10.10.4 (VALLAURIS, France) mardi 14 juillet 2015 16:30:37

Hi. Why only accommodate files that end with “_1”? What is the purpose of a counter if you’re only padding names and not sequencing them?

set AppleScript's text item delimiters to "_"

tell application "Finder" to repeat with anAlias in (get (choose folder)'s files) as alias list --exportPath's files as alias list
	tell (get anAlias's name) to if (count text item 4) = 5 then set anAlias's name to text items 1 thru 3 & ("0" & text item 4) as text
end repeat

set AppleScript's text item delimiters to ""

Thank you for your help, Yvan. I tried your code and the indicated line had an error.

Thanks for the assistance Marc. I had it only changing “_1” files as a test. The only problem I see with your code is that there is no way to know how long the file’s name will be. I only know it will end with an underscore and then the page number.

Puzzling. After defining exportPath by :

set exportpath to (path to desktop folder as text) & “Æ’ sur Le Terminal:dossier sans titre:”

Applying the script when the folder contains “MacOSX_Terminal_part_1.pdf”

The script ended with no error message.
But for sure the file was not renamed because two instructions were incomplete.

Oops. It’s what we get when we post without testing. Here is the corrected version (tested this time)


tell application "Finder"
	set exportFiles to files of folder exportpath
	set count_er to 1
	repeat with i from 1 to count exportFiles
		set fileName to name of item i of exportFiles
		if fileName ends with "_1.pdf" then
			set newName to text 1 thru -6 of fileName & "0" & text -5 thru -1 of fileName
			set name of item i of folder exportpath to newName # EDITED
		else if fileName ends with ".pdf" then
			--set newName to (text 1 thru -5 of fileName) & text -2 thru -1 of ((100 + count_er) as string) & ".pdf" # EDITED
			set newName to (text 1 thru -5 of fileName) & "_" & text -2 thru -1 of ((100 + count_er) as string) & ".pdf" # ALTERNATE
			set name of item i of folder exportpath to newName # EDITED
			set count_er to count_er + 1
		end if
	end repeat
end tell

But re-reading your second message it seems that this other version is matching exactly what you need.

tell application "Finder"
	set exportFiles to files of folder exportpath
	set count_er to 1
	repeat with i from 1 to count exportFiles
		set fileName to name of item i of exportFiles
		if fileName ends with ".pdf" and text -6 of fileName is "_" then
			set newName to text 1 thru -6 of fileName & "0" & text -5 thru -1 of fileName
			set name of item i of folder exportpath to newName # EDITED
		end if
	end repeat
end tell

It inserts a 0 only for files whose name ends with _0.pdf, _1.pdf, _2.pdf, _3.pdf, _4.pdf, _5.pdf, _6.pdf, _7.pdf, _8.pdf, _9.pdf.
In fact it would do the same for names ending with _ (any character) .pdf but you aren’t supposed to have such ones.

Yvan KOENIG running Yosemite 10.10.4 (VALLAURIS, France) mardi 14 juillet 2015 18:39:32

As I didn’t use a character offset method, I don’t understand why you think the length of the text is a concern. Are you planning on exporting files without extensions?

I suppose I misread your code. My mistake. It worked exactly as intended, thank you!

When I ran this code, it failed because it encountered the hidden file named 'Icon
" which does not contain underscore characters.

So, I made a small change :

set AppleScript's text item delimiters to "_"
tell application "Finder" to repeat with anAlias in (get (choose folder)'s files) as alias list --exportPath's files as alias list
	
	set fileName to anAlias's name
	if fileName ends with ".pdf" then
		tell (get anAlias's name) to if (count text item 4) = 5 then set anAlias's name to text items 1 thru 3 & ("0" & text item 4) as text
	end if
end repeat

set AppleScript's text item delimiters to ""

and got an awful : error “Saturation de la pile.” number -2706

As I am pig-headed I made other attempts and ended with :

set AppleScript's text item delimiters to "_"
tell application "Finder" to repeat with anAlias in (get (choose folder)'s files) as alias list --exportPath's files as alias list
	
	set fileName to anAlias's name
	if fileName ends with ".pdf" then
		set nameItems to text items of fileName
		set nbItems to count nameItems
		if (count (nameItems's item nbItems)) = 5 then
			set anAlias's name to items 1 thru (nbItems - 1) of nameItems & ("0" & nameItems's item nbItems) as text
		end if
	end if
end repeat

set AppleScript's text item delimiters to ""

Which works also with the original names contains more or less than three underscore characters

Yvan KOENIG running Yosemite 10.10.4 (VALLAURIS, France) mardi 14 juillet 2015 19:14:04

Hi, Yvan. Thanks for testing. After looking at the events, it appears that the first explicit get was preventing the coercion to alias list, making my “anAlias” variable a misnomer. My approach worked in Mavericks, but only because that coercion failed and it defaulted to using a finder reference; that may not be the case in Yosemite.

Hello

I made new tests and got always the same odd behavior.

set AppleScript's text item delimiters to "_"
set theFolder to (path to desktop as text) & "Æ’ sur  Le Terminal:"

--tell application "Finder" to repeat with anAlias in (get (choose folder)'s files) as alias list --exportPath's files as alias list

tell application "Finder" to repeat with anAlias in (theFolder as alias)'s files as alias list --exportPath's files as alias list
	set fileName to anAlias's name
	log result
	if fileName ends with ".pdf" then
		
		tell fileName
			if (count text item 4) = 5 then
				tell me to log "here I am" # never reached
				set anAlias's name to text items 1 thru 3 & ("0" & text item 4) as text
			end if
		end tell
		
	end if
end repeat

set AppleScript's text item delimiters to ""

The events log is :

tell current application
	path to desktop as text
end tell
tell application "Finder"
	get every file of alias "SSD 500:Users:<myAccount>:Desktop:Æ’ sur  Le Terminal:"
	get name of alias "SSD 500:Users:<myAccount>:Desktop:Æ’ sur  Le Terminal:.DS_Store"
	(*.DS_Store*)
	get name of alias "SSD 500:Users:<myAccount>:Desktop:Æ’ sur  Le Terminal:Icon
"
	(*Icon
*)
	get name of alias "SSD 500:Users:<myAccount>:Desktop:Æ’ sur  Le Terminal:MacOSX_Terminal_part_01.pdf"
	(*MacOSX_Terminal_part_01.pdf*)
	get name of alias "SSD 500:Users:<myAccount>:Desktop:Æ’ sur  Le Terminal:MacOSX_Terminal_part_02.pdf"
	(*MacOSX_Terminal_part_02.pdf*)
	get name of alias "SSD 500:Users:<myAccount>:Desktop:Æ’ sur  Le Terminal:MacOSX_Terminal_part_07.pdf"
	(*MacOSX_Terminal_part_07.pdf*)
	get name of alias "SSD 500:Users:<myAccount>:Desktop:Æ’ sur  Le Terminal:MacOSX_Terminal_part_3.pdf"
	(*MacOSX_Terminal_part_3.pdf*)
end tell
(*here I am*)
Résultat :
error "Saturation de la pile." number -2706

As you see, not only the stack is saturated but the important test is behaving wrongly.

To get a running code I had to edit it as :

set AppleScript's text item delimiters to "_"
set theFolder to (path to desktop as text) & "Æ’ sur  Le Terminal:"

--tell application "Finder" to repeat with anAlias in (get (choose folder)'s files) as alias list --exportPath's files as alias list

tell application "Finder" to repeat with anAlias in (theFolder as alias)'s files as alias list --exportPath's files as alias list
	set fileName to anAlias's name
	log result
	if fileName ends with ".pdf" then
		
		set nameItems to text items of fileName
		try # In case a name doesn't contain three undescore characters
			if (count (item 4 of nameItems)) = 5 then
				tell me to log "here I am" # now it's reached reached
				set anAlias's name to ((items 1 thru 3 of nameItems) & ("0" & (item 4 of nameItems))) as text
			end if
		end try
		
	end if
end repeat

set AppleScript's text item delimiters to ""

But I prefer my late version which is not restricted to a given count of underscore characters.

Yvan KOENIG running Yosemite 10.10.4 (VALLAURIS, France) mercredi 15 juillet 2015 17:44:35

Thanks, but I meant to get across the point that the reason mine initially worked was because my coercion failed. I was under the false impression that I was using an alias, when an alias actually refuses to work with my single-line method. This works (under 10.9) and incorporates your improvements.

set AppleScript's text item delimiters to "_"

tell application "Finder" to repeat with aRef in (get (choose folder)'s files)  --> finder reference(s)
	tell (get aRef's name) to if it ends with ".pdf" and (count text item 4's word 1) = 1 then set aRef's name to text items 1 thru -2 & ("0" & text item -1) as text
end repeat

set AppleScript's text item delimiters to ""

This time it works under 10.10.4.

I introduced three small changes.

(1) No longer work with item 4, work upon item -1 so the script will apply well if names contain variable number of underscore character.
(2) Use (count text item -1) = 5 where you used (count text item 4’s word 1) = 1
because I stay away from word which is language dependant. It’s easier to simply chek that the last item of the list created when we split the name upon underscore is a five character long string : a digit + “.pdf”
(3) I don’t assume that on entry the delimiter in use is “” so I like to save the in use one to restore it on exit.

This said the final code become :

set {oTids, AppleScript's text item delimiters} to {AppleScript's text item delimiters, {"_"}}

tell application "Finder" to repeat with aRef in (get (choose folder)'s files) --> finder reference(s)
	tell (get aRef's name) to if it ends with ".pdf" and (count text item -1) = 5 then set aRef's name to text items 1 thru -2 & ("0" & text item -1) as text
end repeat

set AppleScript's text item delimiters to oTids

Yvan KOENIG running Yosemite 10.10.4 (VALLAURIS, France) mercredi 15 juillet 2015 21:27:58

I am trying to do something similar (splitting PDFs and renaming sequentially.) I’ve got automator neatly doing the splitting, but I am having trouble with the renaming, so if I may ask a question about this. I need to rename batches of files and name them sequentially. My problem is that I need to have it capture the first number in the file name (for example the 68 from: SMP_SEPDM_C01EOC_68_75_annos. Then the others increment sequentially. However, I’m just trying to teach myself this, and I am not finding how to tell it to get the starting variable from a filename.

You may try :

set sourceFolder to choose folder
tell application "Finder"
	set theFiles to files of sourceFolder as alias list
end tell

set cntFile to "count_tnuoc.txt"
set p2AS to path to application support from user domain
set p2Count to (p2AS as text) & cntFile

tell application "System Events"
	if not (exists file p2Count) then
		make new file at end of p2AS with properties {name:cntFile}
		set theCnt to 0
	else
		set theCnt to (read file p2Count) as integer
	end if
	
	repeat with aFile in theFiles # aFile is supposed to be an alias
		set oldName to name of aFile
		--> SMP_SEPDM_C01EOC_68_75_annos.pdf # ADDED
		--> SMP_SEPDM_C01EOC_68_98_annos.pdf # ADDED
		if oldName ends with ".pdf" then # ADDED
			set splittedName to my decoupe(oldName, "_")
			--> {"SMP", "SEPDM", "C01EOC", "68", "75", "annos.pdf"} # ADDED
			--> {"SMP", "SEPDM", "C01EOC", "68", "98", "annos.pdf"} # ADDED
			set splittedNewName to {}
			repeat with txt in splittedName
				set txt to txt as text
				set end of splittedNewName to txt
				if character 1 of txt is in {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"} then exit repeat
			end repeat
			--> {"SMP", "SEPDM", "C01EOC", "68"} # ADDED
			--> {"SMP", "SEPDM", "C01EOC", "68"} # ADDED
			set theCnt to theCnt + 1
			set newName to my recolle(splittedNewName, "_") & "_" & text -2 thru -1 of ((100 + theCnt) as text) & ".pdf"
			--> SMP_SEPDM_C01EOC_68_01.pdf # ADDED
			--> SMP_SEPDM_C01EOC_68_02.pdf # ADDED
			set name of aFile to newName
		end if # ADDED
	end repeat
end tell # System Events
my writeto(p2Count, theCnt, text, false)

#=====

on decoupe(t, d)
	local oTIDs, l
	set {oTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, d}
	set l to text items of t
	set AppleScript's text item delimiters to oTIDs
	return l
end decoupe

#=====

on recolle(l, d)
	local oTIDs, t
	set {oTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, d}
	set t to l as text
	set AppleScript's text item delimiters to oTIDs
	return t
end recolle

#=====
(*
Handler borrowed to Regulus6633 - http://macscripter.net/viewtopic.php?id=36861
*)
on writeto(targetFile, theData, dataType, apendData)
	-- targetFile is the path to the file you want to write
	-- theData is the data you want in the file.
	-- dataType is the data type of theData and it can be text, list, record etc.
	-- apendData is true to append theData to the end of the current contents of the file or false to overwrite it
	try
		set targetFile to targetFile as alias
		set openFile to open for access targetFile with write permission
		if not apendData then set eof of openFile to 0
		write theData to openFile starting at eof as dataType
		close access openFile
		return true
	on error
		try
			close access targetFile
		end try
		return false
	end try
end writeto

#=====

(1) added some comments tracing the intermediate results.
(2) added test checking that the passed file is a pdf one.

Yvan KOENIG running Sierra 10.12.1 in French (VALLAURIS, France) lundi 5 décembre 2016 21:27:03

I feel like I should be able to take it from there, but I’m still having issues. So that script should pick up the first numbers in the file name, right? I ask because I ran it as a way to figure out how I wanted to tinker with it, and it is giving me much larger numbers than I expect, so I think it is getting incremented more necessary. I don’t know whether this is related, but isn’t the script just taking the first digit it finds even if the digit is a multi-digit number?

When I tested with these original file names :
SMP_SEPDM_C01EOC_68_75_annos.pdf
SMP_SEPDM_C01EOC_68_98_annos.pdf
it built these names :
SMP_SEPDM_C01EOC_68_01.pdf
SMP_SEPDM_C01EOC_68_02.pdf
which are what was asked by your question if I understood it correctly.

I’m just wondering if it is useful to add a test checking that the renamed files are really pdf ones.
In my test they were but I don’t know the way you fill the folder.
I wait your feedback before making changes.

I added some comments tracing the intermediate results.

Yvan KOENIG running Sierra 10.12.1 in French (VALLAURIS, France) mardi 6 décembre 2016 11:27:45

Thank you a lot for your help. Today is the one day I work from a PC, so I can’t test it until tomorrow, but I think I was getting larger numbers when I ran the script.

Also, my end goal is actually names like SMP_SEPDM_C01EOC_69.pdf and SMP_SEPDM_C01EOC_70.pdf. The range 68_98 in the original file name is the page range. Which does mean that doing human spot checks will be easy at least.

Maybe it’s due to the fact that English is not my main language but I don’t understand what you want.

What seems sure at this time is that one file is originally named : SMP_SEPDM_C01EOC_68_75_annos.pdf
I don’t guess what are the original names of other files.
Are the files listed in the correct order so that the script may do :

SMP_SEPDM_C01EOC_68_75_annos.pdf → SMP_SEPDM_C01EOC_68.pdf
listed file #2 → SMP_SEPDM_C01EOC_69.pdf
listed file #3 → SMP_SEPDM_C01EOC_70.pdf
and so on

Yvan KOENIG running Sierra 10.12.1 in French (VALLAURIS, France) mardi 6 décembre 2016 14:28:02