Hello there everyone! First post, huzzah!
I’m new to AppleScript (been using Automator for a long while, and thought it was time to ‘upgrade’), so please do bear with me.
I have been attempting to create a script that, when run, will duplicate the selected Finder files a user-specified number of times, ideally with names like “File 1,” “File 2,” etc (incrementing as duplicates are made).
I’ve been reading the tutorials, and have a basic understanding of the language, but so far I have been beating my head against the wall trying to get this to work.
Any help / tips / examples would be greatly appreciated.
Line 1 below gets the number of copies. It should have some error checking to make sure the text returned is a number.
Line 2 collects the selected files as an alias list.
The outer repeat loop treats the collection of files one at a time getting their name and extension and then the base name (without the extension)
The inner loop creates the duplicates and renames them.
-- assuming a file or files have been selected in a Finder window, this script leaves the original name alone and appends a "_N" to the copies.
set N to (text returned of (display dialog "How Many Copies?" default answer "1")) as number
tell application "Finder" to set f to selection as alias list
repeat with oneF in f
tell (info for oneF) to set {Nm, Ex} to {name, name extension}
set BN to text 1 thru ((get offset of "." & Ex in Nm) - 1) of Nm
repeat with k from 1 to N
tell application "Finder"
set dup to duplicate oneF
set name of dup to BN & "_" & k & "." & Ex
end tell
end repeat
end repeat
Thank you so much, Adam. Examining that script has very significantly increased my understanding of the language.
I’ve made some changes to the script, and it’s working great overall. I’ve got some simple error handling, which even mostly works! However, I’d like to improve this a bit more.
There are two main problems:
First, when a user hits cancel at the initial dialog box, they have to then hit cancel again at the “Please enter a numerical value” dialog. I assume this is because I haven’t specified a specific error to be checking for, but I don’t know how to specify the error I want.
The second problem is that my error checking doesn’t really seem to work at all when I’m checking whether or not Finder has any selected items. The dialog box never shows up if there is no selection; the script just quits.
EDIT: Fixed the second problem, just a stupid syntax error. AppleScript is rad, I am falling in love. 
repeat
try
set N to (text returned of (display dialog "How many copies would you like to make?" default answer "1")) as number
set badreply to false
on error
set badreply to true
if badreply then display dialog "Please enter a valid numerical value."
end try
if badreply = false then exit repeat
end repeat
repeat
try
tell application "Finder" to set f to selection as alias list
if f is not {} then exit repeat
if f is {} then display dialog "There are no currently selected finder items. Please select the file(s) to be copied, then press OK."
end try
end repeat
repeat with oneF in f
tell (info for oneF) to set {Nm, Ex} to {name, name extension}
set BN to text 1 thru ((get offset of "." & Ex in Nm) - 1) of Nm
repeat with k from 1 to N
tell application "Finder"
set dup to duplicate oneF
set name of dup to BN & ", copy " & k & " of " & N & "." & Ex
end tell
end repeat
end repeat
This is a bit cleaner:
repeat
set N to (text returned of (display dialog "How many copies would you like to make?" default answer "1")) -- now (outside the "try", "Cancel" will drop out of the script.
try
set N to N as integer -- truncates anything after a decimal point if entered, errors for letters or punctuation.
if N > 0 then exit repeat -- successful conversion, not negative or zero
on error -- couldn't convert to integer
display dialog "Please enter a valid numerical value."
end try
end repeat
repeat
tell application "Finder" to set f to selection as alias list
if (count f) = 0 then
display dialog "There are no currently selected finder items. Please select the file(s) to be copied, then press OK."
else
exit repeat
end if
end repeat
repeat with oneF in f
tell (info for oneF) to set {Nm, Ex} to {name, name extension}
set BN to text 1 thru ((get offset of "." & Ex in Nm) - 1) of Nm
repeat with k from 1 to N
tell application "Finder"
set dup to duplicate oneF
set name of dup to BN & ", copy " & k & " of " & N & "." & Ex
end tell
end repeat
end repeat
Ah, makes perfect sense. Thank you so much Adam, this was precisely what I was trying to accomplish. I was wondering if the try block was what was causing the problem.
I will post here if I make any changes. Thanks again!
For anyone who’s interested, I’ve made some fairly simple changes. Most importantly, the user cannot tell the script to create more than 10,000 copies. Even a fast computer will suffer making thousands of copies.
The way I handled this is not too elegant; I’m simply setting N to 0, knowing that the script will soon cause the loop to repeat if N is found to be 0. It doesn’t matter a whole lot, but is there a simpler way to tell the script to stop what it’s doing and go back? Something like the equivalent of a DOS Batch file’s GOTO would be awesome.
--Ask the user how many copies they're going to want of their file(s).
repeat
set N to (text returned of (display dialog "How many copies would you like to make?" default answer "Please enter a numerical value."))
try
if N > 10000 then
display dialog "The maximum number of copies this script supports is 10,000."
set N to 0
end if
set N to N as integer -- truncates anything after a decimal point if entered, errors for letters or punctuation.
if N > 0 then exit repeat -- successful conversion, not negative or zero
on error -- couldn't convert to integer
display dialog "Please enter a valid numerical value not exceeding 10,000."
end try
end repeat
--Get the selected finder items. If nothing is selected, let the user select something.
repeat
tell application "Finder" to set f to selection as alias list
if (count f) = 0 then
display dialog "There are no currently selected finder items. Please select the file(s) to be copied, then press OK."
else
exit repeat
end if
end repeat
--Finally, duplicate the files with nice incrementing filenames.
repeat with oneF in f
tell (info for oneF) to set {Nm, Ex} to {name, name extension}
set BN to text 1 thru ((get offset of "." & Ex in Nm) - 1) of Nm
repeat with k from 1 to N
tell application "Finder"
set dup to duplicate oneF
set name of dup to BN & ", copy " & k & " of " & N & "." & Ex
end tell
end repeat
end repeat
The usual way to handle that is with an error:
--Ask the user how many copies they're going to want of their file(s).
repeat
set N to (text returned of (display dialog "How many copies would you like to make?" default answer "Please enter a numerical value."))
try
if N > 10000 then error -- this jumps you straight to the "Please enter.... " in the on error section.
set N to N as integer -- truncates anything after a decimal point if entered, errors for letters or punctuation.
if N > 0 then exit repeat -- successful conversion, not negative or zero
on error -- couldn't convert to integer
display dialog "Please enter a valid numerical value not exceeding 10,000."
end try
end repeat
-- and so on
Again, makes perfect sense. The more I mess with AppleScript, the more I like it. I may have found something to replace Batch files in my heart! I just need to stop overcomplicating things that should be simple.
Thanks again Adam, you’ve practically written the entire thing for me.
It’s the only way to learn AppleScript really: by example. When I joined MacScripter in 2002 (under another name – it used to be NovaScotian) there were lot’s of willing tutors, so I try to give back.