Hello everyone. I could use some help with this script please. What this script does is convert an entire folder of files that are named in EPOCH time to a readable Date/Time format, for example, converting 1536081602636.mp4 to 2018/09/04 | 13_20_02.
The problem I am having is that many of the files are only slightly different in EPOCH time, i.e. 1536081602637.mp4 as compared to above, so they are technically different file names, but when they are getting converted, the conversion remains the same Date/Time as the previous file, which causes Applescript to throw a duplicate file error and stop.
I need help modifying the script so that before it does the rename at the end, it checks to see if the final file name already exists, and if so, it adds one second to the name to make it unique, so that in the above example, it would rename the file 1536081602637.mp4 to 2018/09/04 | 13_20_03 to avoid the problem (and to just make sure there aren’t two the same, it would do it recursively until it found a name that was not already in use)
Thanks to anyone who can help me!
tell application “Finder” to set theFiles to every file of folder (“Hard Drive:Users:MacUser:Downloads” as text)
repeat with xFile in theFiles
set {TID, text item delimiters} to {text item delimiters, “.”}
set epochseconds to text 1 thru -8 of (name of xFile as text)
set theDate to “date -r "
set modTime to " "+%Y/%m/%d %H:%M:%S"”
set modName to do shell script (theDate & epochseconds & modTime)
set timeStamp to modName as string
log words of timeStamp
set modDate to the current date
set year of modDate to word 1 of timeStamp
set month of modDate to word 2 of timeStamp
set day of modDate to word 3 of timeStamp
set time of modDate to ((word 4 of timeStamp) * hours + (word 5 of timeStamp) * minutes + ((word 6 of timeStamp) / 60) * minutes)
set xFile’s modification date to modDate
set fileTime to " "+%Y/%m/%d %H_%M_%S""
set fileName to do shell script (theDate & epochseconds & fileTime)
set xFile’s name to text 1 thru 11 of fileName & "| " & text 12 thru 19 of fileName & “.mp4”
end repeat
Hi.
A fairly simple idea, if it suited you, would be to keep the odd milliseconds in the names as fractional parts of the seconds: “2018/09/04 13_20_02.636.mp4” or “2018/09/04 13_20_02_636.mp4”. It’s probably doable with a shell script, but I’ve used ASObjC in this demo:
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
-- Set up a date formatter at the top of the script.
set dateFormatter to current application's class "NSDateFormatter"'s new()
tell dateFormatter to setDateFormat:("yyyy/MM/dd HH_mm_ss.SSS")
set {TID, text item delimiters} to {text item delimiters, "."}
-- repeat with xFile in theFiles
set fileName to "1536081602636.mp4"
-- The file name up to the extension is a number of milliseconds. Divide it by 1000 to get it in fractional seconds.
set epochseconds to (text 1 thru text item -2 of fileName) / 1000
-- Get the NSDate corresponding to the result in Unix time.
set NSDate to current application's class "NSDate"'s dateWithTimeIntervalSince1970:(epochseconds)
-- Format a local-time string from that and add the original extension.
set newFileName to ((dateFormatter's stringFromDate:(NSDate)) as text) & ("." & text item -1 of fileName)
--> "2018/09/04 18_20_02.636.mp4" in my locale, "2018/09/04 13_20_02.636.mp4" in yours.
-- end repeat
--set text item delimiters to TID
Actually, I need to replace the milliseconds with rounded seconds to maintain the required format. Is there a way to do this more along the lines I had intended, which is to test for the presence of a file name and if its exists, to round the “seconds” up one to avoid duplicate names?
Here are two versions. The first sets modification dates derived from the original epoch seconds and the second sets modification dates matching the new file names.
-- This version sets modification dates based on the original epoch seconds.
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
tell application "Finder"
set theFolder to folder "Hard Drive:Users:MacUser:Downloads"
set fileNames to name of every file of theFolder
end tell
set dateFormatter to current application's class "NSDateFormatter"'s new()
tell dateFormatter to setDateFormat:("yyyy/MM/dd | HH_mm_ss")
set usedEpochSeconds to {}
set {TID, text item delimiters} to {text item delimiters, "."}
repeat with originalName in fileNames
-- Extract the epoch seconds from this name.
set epochSeconds to (text 1 thru text item -2 of originalName) div 1000
-- Convert to NSDate and thence to AS date to use for the file's modification date.
set originalDate to (current application's class "NSDate"'s dateWithTimeIntervalSince1970:(epochSeconds))
-- (In El Capitan and later, originalDate can simply be coerced to date here. But the following works in Yosemite too.)
set originalDate to (dateFormatter's stringFromDate:(originalDate)) as text
set text item delimiters to {"/", " | ", "_"}
tell (current date) to set {newModDate, day, {year, its month, day, its hours, its minutes, its seconds}} to {it, 1, originalDate's text items}
set text item delimiters to "."
-- Increment the epoch seconds if/as necessary to ensure a unique number and store the number arrived at.
repeat while (usedEpochSeconds contains epochSeconds)
set epochSeconds to epochSeconds + 1
end repeat
set end of usedEpochSeconds to epochSeconds
-- Derive a new, formatted-date file name from this number and the original name extension.
set nameDate to (current application's class "NSDate"'s dateWithTimeIntervalSince1970:(epochSeconds))
set newName to ((dateFormatter's stringFromDate:(nameDate)) as text) & ("." & text item -1 of originalName)
-- Set the file's modification date and name (in that order!) to the new values.
tell application "Finder"
set modification date of file originalName of theFolder to newModDate
set name of file originalName of theFolder to newName
end tell
end repeat
set text item delimiters to TID
-- Move the files to a new folder (assumed already to exist).
tell application "Finder" to move every file of theFolder to folder "Hard Drive:Users:MacUser:Documents:Archived Files" with replacing
-- This version sets modification dates matching the new names.
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
tell application "Finder"
set theFolder to folder "Hard Drive:Users:MacUser:Downloads"
set fileNames to name of every file of theFolder
end tell
set dateFormatter to current application's class "NSDateFormatter"'s new()
tell dateFormatter to setDateFormat:("yyyy/MM/dd | HH_mm_ss")
set usedEpochSeconds to {}
set {TID, text item delimiters} to {text item delimiters, "."}
repeat with originalName in fileNames
-- Extract the epoch seconds from this name.
set epochSeconds to (text 1 thru text item -2 of originalName) div 1000
-- Increment if/as necessary to ensure a unique number and store the number arrived at.
repeat while (usedEpochSeconds contains epochSeconds)
set epochSeconds to epochSeconds + 1
end repeat
set end of usedEpochSeconds to epochSeconds
-- Convert to NSDate and derive a formatted date string.
set nameDate to (current application's class "NSDate"'s dateWithTimeIntervalSince1970:(epochSeconds))
set formattedNameDate to (dateFormatter's stringFromDate:(nameDate)) as text
-- Derive an AS date from this to use for the file's modification date.
-- (In El Capitan and later, nameDate can simply be coerced to date here. But the following works in Yosemite too.)
set text item delimiters to {"/", " | ", "_"}
tell (current date) to set {newModDate, day, {year, its month, day, its hours, its minutes, its seconds}} to {it, 1, formattedNameDate's text items}
set text item delimiters to "."
-- Make a new file name from the formatted date and the original name extension.
set newName to formattedNameDate & ("." & text item -1 of originalName)
-- Set the file's modification date and name (in that order!) to the new values.
tell application "Finder"
set modification date of file originalName of theFolder to newModDate
set name of file originalName of theFolder to newName
end tell
end repeat
set text item delimiters to TID
-- Move the files to a new folder (assumed already to exist).
tell application "Finder" to move every file of theFolder to folder "Hard Drive:Users:MacUser:Documents:Archived Files" with replacing
Edit: Second script corrected and both augmented as discussed below.
Wow, thanks! Interestingly, only the first script worked, the second gives an error, and in any event, I am not sure what the difference is supposed to be between them,
I just need one more thing. The named format needs to have the “|” divider between date and time, like this:
2018/09/05 | 23_53_18.mp4.
Can you please modify Script 1 for this output?
Thanks again.
Oh, now I see the difference, and the second version setting the mod time to the name is what I need but it doesn’t work. The error I get is:
Can’t make «class ocid» id «data optr000000000D0000A3B0A0C041» into type list, record or text.
One more thing…
Can you please add a line at the end of the script to move all the files in the folder to another location (“Hard Drive:Users:MacUser:Documents:Archived Files”) after the renaming is done?
Thanks!
For the vertical bar, replace :
set newName to ((dateFormatter's stringFromDate:(nameDate)) as text) & ("." & text item -1 of originalName)
by
# create with standard format
set newName to ((dateFormatter's stringFromDate:(nameDate)) as text)
# insert the vertical bar
set newName to text 1 thru 11 of newName & "|" & text 11 thru -1 of newName & ("." & text item -1 of originalName)
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) jeudi 6 septembre 2018 16:31:03
That worked perfectly!
The only remaining items I need are to set the mod date/time to the newly named file and not the original epoch time as in script 2 (for some reason, it errors out), and to move all the files in the folder to another location.
Sorry. For some reason, the script was trying to set the new name to the NSDate plus the extension instead of to the formatted date string and extension. I’m sure I tested both scripts before posting. Anyway, I’ve corrected it above now and am just about to look at the other points you’ve raised.
Edit: Now done.