I use Opus to rename thousands of files but I have up to now mostly stuck with the built-in renaming options. I am trying to take a stab at a script that will change multiple parts of a filename in one go and could use some assistance.
I have thousands of files that have this naming structure
Title-Camera#-YYYY-Month-DD-hh-mm-ss-PM-notes.ext.ext
Example filenames:
PhotoXPS-cam#1-2019-Jun-13-05-47-16-PM.avi
TreeCam-cam#3-2019-Oct-13-08-20-27-AM-tree.avi.jpg
These are terrible because not only are they messy to look at they also fail to sort because of the spelled-out month and the 12 hour time.
Ideally I would like the above examples to rename to something like this:
PhotoXPS-cam#1-2019-Jun-13-05-47-16-PM.avi
-> PhotoXPS - 2019-06-13 174716.avi
TreeCam-cam#3-2019-Oct-13-08-20-27-AM-tree.avi.jpg
-> TreeCam - 2019-10-13 082027-tree.jpg
Notice that sometimes there are extra notes at the end of the files.
Also, note that sometimes there are extra extensions that I do not need to keep
I started with this:
function OnGetNewName(getNewNameData)
{
// Convert Variant strings to JScript String objects so we can use String methods.
var strExtension = String(getNewNameData.newname_ext_m);
var strNameOnly = String(getNewNameData.newname_stem_m);
// Replace cams with dash.
strNameOnly = strNameOnly.replace (/-cam#[123]-/g, " - ");
// Case-sensitive, replace months with numbers.
strNameOnly = strNameOnly.replace(/Jan/g, "01");
strNameOnly = strNameOnly.replace(/Feb/g, "02");
strNameOnly = strNameOnly.replace(/Mar/g, "03");
strNameOnly = strNameOnly.replace(/Apr/g, "04");
strNameOnly = strNameOnly.replace(/May/g, "05");
strNameOnly = strNameOnly.replace(/Jun/g, "06");
strNameOnly = strNameOnly.replace(/Jul/g, "07");
strNameOnly = strNameOnly.replace(/Aug/g, "08");
strNameOnly = strNameOnly.replace(/Sep/g, "09");
strNameOnly = strNameOnly.replace(/Oct/g, "10");
strNameOnly = strNameOnly.replace(/Nov/g, "11");
strNameOnly = strNameOnly.replace(/Dec/g, "12");
// Rejoin the name and extension and return the result.
return strNameOnly + strExtension;
This gets me closer by outputting filenames like these
PhotoXPS-cam#1-2019-Jun-13-05-47-16-PM.avi
-> PhotoXPS - 2019-06-13-05-47-16-PM.avi
TreeCam-cam#3-2019-Oct-13-08-20-27-AM-tree.avi.jpg
-> TreeCam - 2019-10-13-08-20-27-AM-tree.avi.jpg
I then added:
// Replace Dash between date and time with " " .
search = '-'
var n = 4
strNameOnly = (strNameOnly.replace(RegExp("^(?:.*?-){" + n + "}"), function(x){return x.replace(RegExp(search + "$"), " ")}))
// Replace Dash between time with "~" .
search = '-'
var n = 4
strNameOnly = (strNameOnly.replace(RegExp("^(?:.*?-){" + n + "}"), function(x){return x.replace(RegExp(search + "$"), "~")}))
strNameOnly = (strNameOnly.replace(RegExp("^(?:.*?-){" + n + "}"), function(x){return x.replace(RegExp(search + "$"), "~")}))
// Replace Dash before PM with " " .
search = '-'
var n = 4
strNameOnly = (strNameOnly.replace(RegExp("^(?:.*?-){" + n + "}"), function(x){return x.replace(RegExp(search + "$"), " ")}))
This further improved the filenames to
PhotoXPS-cam#1-2019-Jun-13-05-47-16-PM.avi
-> PhotoXPS - 2019-06-13 05~47~16 PM.avi
TreeCam-cam#3-2019-Oct-13-08-20-27-AM-tree.avi.jpg
-> TreeCam - 2019-10-13 08~20~27 AM-tree.avi.jpg
( "~" was added to time so I had something unique to work with on the next step.)
This part of the script introduced my first issue, however; because searching for the 4th "-" can really screw up a filename that has already been renamed. I would prefer a way to search for the 4th "-" but exclude any "-" that has a letter next to it. That way it won't replace the dash at the end of the file name where I may have a note.
The final step I was trying to accomplish was converting AM/PM to 24 hour time.
I ran into this page 24-hour conversion in JS that has dozens of methods to accomplish this task.
The one I tried to insert into my script, unfortunately, breaks it.
// Convert a string like 10~05~23 PM to 24h format, returns like [22-05-23]
var s = strNameOnly.match(/(\d+)~(\d+)~(\d+) (\w)+/g);
var time = s.match(/\d{2}/g);
if (time[0] === "12") time[0] = "00";
if (s.indexOf("PM") > -1) time[0] = parseInt(time[0])+12;
return time.join("");
I thought I could use the regex (/(\d+)~(\d+)~(\d+) (\w)+/g) to only edit the part of the filename with the time and then have it convert and place it all back together.
But alas my lack of skills in scripting either results in breaking the script or outputting a filename that only has a timestamp and nothing else.
Here is my script in its entirety.
function OnGetNewName(getNewNameData)
{
// Convert Variant strings to JScript String objects so we can use String methods.
var strExtension = String(getNewNameData.newname_ext_m);
var strNameOnly = String(getNewNameData.newname_stem_m);
// Replace cams with dash.
strNameOnly = strNameOnly.replace (/-cam#[123]-/g, " - ");
// Replace months with numbers.
strNameOnly = strNameOnly.replace(/Jan/g, "01");
strNameOnly = strNameOnly.replace(/Feb/g, "02");
strNameOnly = strNameOnly.replace(/Mar/g, "03");
strNameOnly = strNameOnly.replace(/Apr/g, "04");
strNameOnly = strNameOnly.replace(/May/g, "05");
strNameOnly = strNameOnly.replace(/Jun/g, "06");
strNameOnly = strNameOnly.replace(/Jul/g, "07");
strNameOnly = strNameOnly.replace(/Aug/g, "08");
strNameOnly = strNameOnly.replace(/Sep/g, "09");
strNameOnly = strNameOnly.replace(/Oct/g, "10");
strNameOnly = strNameOnly.replace(/Nov/g, "11");
strNameOnly = strNameOnly.replace(/Dec/g, "12");
// Replace Dash between date and time with " " .
search = '-'
var n = 4
strNameOnly = (strNameOnly.replace(RegExp("^(?:.*?-){" + n + "}"), function(x){return x.replace(RegExp(search + "$"), " ")}))
// Replace Dash between time with "~" .
search = '-'
var n = 4
strNameOnly = (strNameOnly.replace(RegExp("^(?:.*?-){" + n + "}"), function(x){return x.replace(RegExp(search + "$"), "~")}))
strNameOnly = (strNameOnly.replace(RegExp("^(?:.*?-){" + n + "}"), function(x){return x.replace(RegExp(search + "$"), "~")}))
// Replace Dash before PM with " " .
search = '-'
var n = 4
strNameOnly = (strNameOnly.replace(RegExp("^(?:.*?-){" + n + "}"), function(x){return x.replace(RegExp(search + "$"), " ")}))
// Convert a string like 10~05~23 PM to 24h format, returns like [22-05-23]
var s = strNameOnly.match(/(\d+)~(\d+)~(\d+) (\w)+/g);
var time = s.match(/\d{2}/g);
if (time[0] === "12") time[0] = "00";
if (s.indexOf("PM") > -1) time[0] = parseInt(time[0])+12;
return time.join("");
// Rejoin the name and extension and return the result.
return strNameOnly + strExtension;
}
Thanks for any help.