Is it possible to get applescript to give me a unique file name (possibly based off date/time/milliseconds) ?
You could use Jon’s Commands’ “the ticks” or “GetMilliSec”. You can find both scripting additions at http://www.osaxen.com/
This, though, doesn’t ensure a unique file name… Here is a pair of handlers which will create “original” names:
(*
sequentialName
Creates a new file path based on an existing file or folder.
If you take a look to the code, you can uncomment certain lines to add:
- Prefix support: a prefix will be added before the sequential number. For example:
sequentialName(alias "path:to:file.txt", "_")
eg: file.txt --> file_1.txt
- Leading zeroes support: returns the specified number of leading zeroes if needed. For example:
sequentialName(alias "path:to:file.txt", "0000")
file.txt --> file0001.txt
- Support for both prefix and leading zeroes
sequentialName(alias "path:to:file.txt", "G", "000")
file.txt --> fileG001.txt
Just search this script for "uncomment this" and follow the instructions.
Parameters:
existingFile: alias or path to an existing file or folder. Eg: alias "path:to:file.txt"
Example:
sequentialName(alias "path:to:file.txt") --> "path:to:file1.txt" (if "file1.txt" exists, it will return "file2.txt")
sequentialName(alias "path:to:") --> "path:to1:" (if "to1" exists, it will return "to2")
*)
-- to sequentialName(existingFile,prefix) --> uncomment this if you will use a prefix before the sequential number. Eg: file.txt --> file_1.txt
-- to sequentialName(existingFile,leading) --> uncomment this if you will use leading zeroes. Eg: file.txt --> file001.txt
-- to sequentialName(existingFile,prefix,leading) --> uncomment this if you will use both prefix and leading zeroes. Eg: file.txt --> file_01.txt
to sequentialName(existingFile)
set existingFile to existingFile as text
set isFolder to existingFile ends with ":"
if isFolder then --> keep out ":"
set enclosingFolder to text 1 thru -2 of existingFile
else
--> get enclosing folder and file name
set previousTID to text item delimiters
set AppleScript's text item delimiters to ":"
set fileTextItems to text items of existingFile
set enclosingFolder to "" & items 1 thru -2 of fileTextItems & ":"
set fileName to item -1 of fileTextItems
set AppleScript's text item delimiters to previousTID
--> get file name and extension
set fileExtension to "" --> just in case there is not file extension
try
set reverseName to reverse of fileName's items as text
set offsetOfDot to offset of "." in reverseName
set fileExtension to text -offsetOfDot thru -1 of fileName
set fileName to text 1 thru -(offsetOfDot + 1) of fileName
end try
if fileName is fileExtension then set fileName to "" --> file starts with a dot, eg ".DS_Store"
end if
--> create new sequential file name
set addOn to ""
repeat
try
if isFolder then
--> uncomment this and delete the existing to add prefix support
--set newFile to enclosingFolder & prefix & addOn & ":"
--> uncomment this and delete the existing to add leading support
--set newFile to enclosingFolder & (text -(count leading) thru -1 of (leading & addOn)) & ":"
--> uncomment this and delete the existing to add prefix and leading zeroes support
--set newFile to enclosingFolder & prefix & (text -(count leading) thru -1 of (leading & addOn)) & ":"
set newFile to enclosingFolder & addOn & ":"
else
--> uncomment this and delete the existing to add prefix support
--set newFile to enclosingFolder & fileName & prefix & addOn & fileExtension
--> uncomment this and delete the existing to add leading support
--set newFile to enclosingFolder & fileName & (text -(count leading) thru -1 of (leading & addOn)) & fileExtension
--> uncomment this and delete the existing to add prefix and leading zeroes support
--set newFile to enclosingFolder & fileName & prefix & (text -(count leading) thru -1 of (leading & addOn)) & fileExtension
set newFile to enclosingFolder & fileName & addOn & fileExtension
end if
alias newFile
--> exists!!!
set addOn to addOn + 1
on error
return newFile
end try
end repeat
end sequentialName
(*
sequentialNameBinary
Creates a new file path based on an existing file or folder, performing a "binary guess":
- Let's supposse that you have file1, file2, file3, file4, file5, and you want a new reference to create file6
- sequentialNameBinary searches for file1, then for file2, then for file4, then for file8, then for file6 (in between)
- So, now imagine the improvements against "sequentialName", which simply adds 1 every time: it searches for file1, 2, 3, 4, 5, 6
- But now imagine you need a reference to create the file89. Instead of searching 89 times, sequentialNameBinary searches only 14 times: 1,2,4,8,16,32,64,128[then back],96[between 64 and 128],80,88,92,90,89
- Now, one more time... What if you need file703? sequentialName will loop 703 times, and sequentialNameBinary will do it only 20 times... (math yourself to calculate the results)
- The algorithm can be improved in speed, sure, but I'm not NG nor AK nor HS nor PB nor KE nor PS nor lots of other people ;-)
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
So, use this handler if you expect large amounts of existing files with sequential names.
Otherwise (you expect only two or three or six sequential file names), use sequentialName
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
If you take a look to the code, you can uncomment certain lines to add:
- Prefix support: a prefix will be added before the sequential number. For example:
sequentialNameBinary(alias "path:to:file.txt", "_")
eg: file.txt --> file_1.txt
- Leading zeroes support: returns the specified number of leading zeroes if needed. For example:
sequentialNameBinary(alias "path:to:file.txt", "0000")
file.txt --> file0001.txt
- Support for both prefix and leading zeroes
sequentialNameBinary(alias "path:to:file.txt", "G", "000")
file.txt --> fileG001.txt
Just search this script for "uncomment this" and follow the instructions.
Parameters:
existingFile: posix path, alias or path to an existing file or folder.
[prefix]: some text preceding the sequential number. Eg: "_" (file.txt --> file_1.txt)
[leading]: formatting of sequential numbers. Eg: "000" (file.txt --> file001.txt) or "0000" (file.txt --> file0001.txt)
Example:
sequentialNameBinary(alias "path:to:file.txt") --> "path:to:file1.txt" (if "file1.txt" exists, it will return "file2.txt")
sequentialNameBinary(alias "path:to:") --> "path:to1:" (if "to1" exists, it will return "to2")
*)
-- to sequentialNameBinary(existingFile,prefix) --> uncomment this if you will use a prefix before the sequential number. Eg: file.txt --> file_1.txt
-- to sequentialNameBinary(existingFile,leading) --> uncomment this if you will use leading zeroes. Eg: file.txt --> file001.txt
-- to sequentialNameBinary(existingFile,prefix,leading) --> uncomment this if you will use both prefix and leading zeroes. Eg: file.txt --> file_01.txt
to sequentialNameBinary(existingFile)
set existingFile to existingFile as Unicode text
if existingFile does not contain ":" then set existingFile to POSIX file existingFile as Unicode text
set isFolder to existingFile ends with ":"
if isFolder then --> keep out ":"
set enclosingFolder to text 1 thru -2 of existingFile
else
--> get enclosing folder and file name
set previousTID to text item delimiters
set AppleScript's text item delimiters to ":"
set fileTextItems to text items of existingFile
set enclosingFolder to "" & items 1 thru -2 of fileTextItems & ":"
set fileName to item -1 of fileTextItems
set AppleScript's text item delimiters to previousTID
--> get file name and extension
set fileExtension to "" --> just in case there is not file extension
try
set reverseName to reverse of fileName's text items as text
set offsetOfDot to offset of "." in reverseName
set fileExtension to text -offsetOfDot thru -1 of fileName
set fileName to text 1 thru -(offsetOfDot + 1) of fileName
end try
if fileName is fileExtension then set fileName to "" --> file starts with a dot, eg ".DS_Store"
end if
--> create new sequential file name
set min to 1
set max to 0
set oldMin to 0
set |mode| to 1
repeat
try
if isFolder then
--> uncomment this and delete the existing to add prefix support
--set newFile to enclosingFolder & prefix & min & ":"
--> uncomment this and delete the existing to add leading support
--set newFile to enclosingFolder & (text -(count leading) thru -1 of (leading & min)) & ":"
--> uncomment this and delete the existing to add prefix and leading zeroes support
--set newFile to enclosingFolder & prefix & (text -(count leading) thru -1 of (leading & min)) & ":"
set newFile to enclosingFolder & min & ":"
else
--> uncomment this and delete the existing to add prefix support
--set newFile to enclosingFolder & fileName & prefix & min & fileExtension
--> uncomment this and delete the existing to add leading support
--set newFile to enclosingFolder & fileName & (text -(count leading) thru -1 of (leading & min)) & fileExtension
--> uncomment this and delete the existing to add prefix and leading zeroes support
--set newFile to enclosingFolder & fileName & prefix & (text -(count leading) thru -1 of (leading & min)) & fileExtension
set newFile to enclosingFolder & fileName & min & fileExtension
end if
alias newFile
--> exists!!!
set oldMin to min
if |mode| is 1 then
set min to min * 2
else
set tmpMin to min + ((max - min) / 2)
if tmpMin's class is not integer then --> adjust even
set oldMin to 0.1
set min to (tmpMin + 0.5) as integer
else
set min to tmpMin
end if
end if
on error
--> rewind a bit
set |mode| to 0
set max to min
set min to oldMin + ((max - oldMin) / 2)
if min's class is not integer then return newFile
end try
end repeat
end sequentialNameBinary