Script to Update "Created/Modified Date" Based on File Name

Discuss and share scripts and script files...
flavarite
Posts: 2
Joined: 05 Jun 2010 07:41

Script to Update "Created/Modified Date" Based on File Name

Post by flavarite »

Hello everyone...newcomer here. I have 100's of movie files from my point and shoot camera where the created and modified dates are not correct. Each file name actually contains the date they were taken so I'd like to update all files to show the correct created date to the file name (while we are at it..just set the modified date to the same value as the created date. I came across one Stefan's (community member) posts on another website (http://www.bulkrenameutility.co.uk/foru ... ?f=4&t=454) where he posted a reply about using a script you provided which can update the "Created Date" of a file based on the name of that file. That worked for one file, but would like to do a batch of files in one update. In XYPlorer I loaded his script below and selected 10 files. When I ran the script, the created date of all 10 files were updated to the same date based on the filename of the first file I had selected. I'm assuming the script below was meant for one file at a time as it does not loop through.

Any chance you can help? Thanks in advance

Code: Select all

$date = regexreplace("<curbase>", "(\d{4})(\d{2})(\d{2})_(\d{2})(\d{2})(\d{2})_.+", "$1-$2-$3 $4:$5:$6");
timestamp c, $date;
I found another post on this forum which used a loop statement to work through the files someone else wanted to update. There script is below...not sure if there's a way to merge these two. Maybe there's another way to do it...just thought I'd share what I found.

Code: Select all

"Text Loop"
   $filelist = getinfo('SelectedItemsPathNames', '|');
   $count=1;
   while(1){
      $file=gettoken($filelist,$count,"|");
      if("$file"==""){break;}
      $data=regexreplace(readfile("$file"), "\n", "<crlf>");
      $base=regexreplace($file,"^(.+)\..+?$","$1");
      writefile("$base.nfo", "$data");
      $count++;}
   status "Done!",,ready;

Stefan
Posts: 1360
Joined: 18 Nov 2008 21:47
Location: Europe

Re: Script to Update "Created/Modified Date" Based on File Name

Post by Stefan »

UPDATE: see >here< for an update of that script with syntax of 2011

- - -

Hi flavarite, welcome.


flavarite> In XYPlorer I loaded your script below and selected 10 files. When I ran the script, the created date
flavarite> of all 10 files were updated to the same date based on the filename of the first file I had selected.


Yes you are right, the date to set is one time build and stored into the var $date and then used for all selected files.
To make this $date unique for every file we have to calculate the date for every file again.



This "loop" script you have found is good to use for what we need here, good work of you!
Here's this script stripped down to the pure base with some comments for better understanding:

Code: Select all

"Loop through selected files"
    //collect the selected files into var $fileslist:
   $filelist = getinfo('SelectedItemsPathNames', '|');
   //initialize loop-counter var:
   $count=1;
   //start an infinity loop:
   while(1){
       //put one file after the other into var $file:
      $file=gettoken($filelist,$count,"|");
	  //if var $file is empty break the script:
      if("$file"==""){break;}
	  
	  //your script here

      //increase the count by one, to get the next file from filelist in the next loop
      $count++;}
   //just an info for the user:
   status "Done!",,ready;
Press F1 in XYplorer and read "Advanced Topics > Scripting Commands Reference" to understand what this commands do and how to modify them.
For more about scripting and how to execute an script read the wiki at http://88.191.26.34/XYwiki/index.php/Scripting


So the working script for your issue should look like:
(see >here< for an update of that script with syntax of 2011)

Code: Select all

"Set date from filename"
   $filelist = getinfo('SelectedItemsPathNames', '|');
   $count=1;
   while(1){
      $file=gettoken($filelist,$count,"|");
      if("$file"==""){break;}
	  
	  //your code here
	  $RegExFind = ".+_(\d{4})(\d{2})(\d{2})_(\d{2})(\d{2})(\d{2})\..*";
	  $RegExReplace = "$1-$2-$3 $4:$5:$6";
	  $date = regexreplace("$file", $RegExFind, $RegExReplace);
      timestamp mc, $date, $file;


      $count++;}
   status "Done!",,ready;
   beep 800,100; beep 400,100; beep 600,100;
   
You see that i have replaced "<curbase>" by $file? And added 'm' to the timestamp parameter.
And i have added an third parameter for the timestamp command to add this time stamp to current processed file only?

But please note that the pattern in the command regexreplace ONLY match for file names like:
"0001_20091104_184344" (where "20091104" is YYYYMMDD & "184344" is 6:43:44 PM)
So i guess you have to modify the regex expression, as you have already, if i see your quote correct.


Some hints about RegEx
* online tester:
- http://rereplace.com/
- http://www.regextester.com/
- http://www.regexlib.com/RETester.aspx

* online help:
- http://www.regular-expressions.info
- http://www.regexlib.com/
- http://www.regexlib.com/CheatSheet.aspx


HTH? :D
Last edited by Stefan on 21 Jun 2011 10:00, edited 1 time in total.

admin
Site Admin
Posts: 64900
Joined: 22 May 2004 16:48
Location: Win8.1, Win10, Win11, all @100%
Contact:

Re: Script to Update "Created/Modified Date" Based on File Name

Post by admin »

Just a little remark: There's no need to put "$file" in quotes.

Stefan
Posts: 1360
Joined: 18 Nov 2008 21:47
Location: Europe

Re: Script to Update "Created/Modified Date" Based on File Name

Post by Stefan »

admin wrote:Just a little remark: There's no need to put "$file" in quotes.
Thanks, i will try to remind this by my next script :D

I am still always unsure with quotes.
(and rather like to add them then leave them... and don't really care as long as it works. But will try next time again.)

flavarite
Posts: 2
Joined: 05 Jun 2010 07:41

Re: Script to Update "Created/Modified Date" Based on File Name

Post by flavarite »

Stefan,
A million thanks!!! :D

I have been able to use the script you provided to modify all my movie files creation and modified dates based on the file name. I used the script below (slightly modified the format of the $RegExFind to handle the format of my file names (ex. 20100509_120000_mvi_0225.mov).

I really appreciate your help...since I was able to do this...I was finally able to use another application to automatically restructure all my pictures and movies into a more meaningful directory structure. Where; over time, each time I pulled new movies and pics from my cameras i was creating a new folder for each "date taken". I had 100s of directories. Using a program called ROBOFOLDER (http://www.picajet.com/en/index.php?page=robofolder), it analyzed each pictures "date taken" date and put them into a structure like: ..\2009\Summer\08-August\, ..\2010\Spring\05-May\, etc. That program was not working for my movies as the movie files did not have the "date taken" attribute in the file. As an alternate ROBOFOLDER can use the "date created" to do the same type of restructuring. Once the date created for each movie file was corrected I could run ROBOFOLDER against the movie files and dump them automajically into the same directory structure.

Note sure if there are other programs out there that do what ROBOFOLDER does but in conjunction with XYPLOYER and Stefan's code I was able to accomplish my project. Oh...I had also used "Bulk Rename Utility" (http://www.bulkrenameutility.co.uk) to handle the renaming of my movie files to be in the necessary format (20100509_120000_mvi_0225.mov).

For those interested; I did the following:

1.) Using Bulk Rename Utility - Renamed all my movie file names to include the name of the folder (20100509) they were in (which was the date they were taken) and a fake time stamp of 12PM (_120000). This was prepended to my existing file name (_mvi_0225.mov) to make the new name: 20100509_120000_mvi_0225.mov
2.) Then used XYPLORER to find all the MOVIE files i updated and ran Stefan's script below to update the CREATED and MODIFIED date based on the above file name.
3.) Then used ROBOFOLDER to automatically move all movies to the new directories based on their creation date. So the above example moved to: ..\2010\Spring\05-May\

Code: Select all

"Set date from filename"
   $filelist = getinfo('SelectedItemsPathNames', '|');
   $count=1;
   while(1){
      $file=gettoken($filelist,$count,"|");
      if("$file"==""){break;}
     
     //your code here
     $RegExFind = ".+(\d{4})(\d{2})(\d{2})_(\d{2})(\d{2})(\d{2})_.+", "$1-$2-$3 $4:$5:$6";
     $RegExReplace = "$1-$2-$3 $4:$5:$6";
     $date = regexreplace("$file", $RegExFind, $RegExReplace);
      timestamp mc, $date, $file;


      $count++;}
   status "Done!",,ready;
   beep 800,100; beep 400,100; beep 600,100;

Stefan
Posts: 1360
Joined: 18 Nov 2008 21:47
Location: Europe

Re: Script to Update "Created/Modified Date" Based on File Name

Post by Stefan »

Hi flavarite, great it works, thanks for the response.
In future you can make all this work inside XYplorer, if you want :D
flavarite wrote:1.) Using Bulk Rename Utility - Renamed all my movie file names to include the name of the folder (20100509) they were in (which was the date they were taken) and a fake time stamp of 12PM (_120000). This was prepended to my existing file name (_mvi_0225.mov) to make the new name: 20100509_120000_mvi_0225.mov
FROM mvi_0225.mov
TO ParentFolderName_120000_mvi_0225.mov

Select an copy of your file "mvi_0225.mov" and paste this code into "Scripting > Try Script..."
Pseudo Code:

Code: Select all

//your code here
    //rename file "*.*" to "parentfoldername_120000_*.*"
    rename b,"<curfolder>_120000_*";

flavarite wrote:3.) Then used ROBOFOLDER to automatically move all movies to the new directories based on their creation date. So the above example moved to: ..\2010\Spring\05-May\
Based on "20100509_120000_mvi_0225.mov"
to: "..\2010\Spring\05-May\mvi_0225.mov"

Select an copy of your file "20100509_120000_mvi_0225.mov" and paste this code into "Scripting > Try Script..."
Pseudo Code:

Code: Select all

     $RegExFind = "(\d{4})(\d{2})(\d{2})_(\d{2})(\d{2})(\d{2})_.+";
     $RegExReplace = "$1-$2-$3 $4:$5:$6";
     $date = regexreplace("<curbase>", $RegExFind, $RegExReplace);
     msg Date found: $date;

     $year = substr($date, 0,4);  
     $month = substr($date, 5,2);
     $day = substr($date, 8,2);

     if ($month>2 && < 6){$season="Spring";}
     if ($month=="05"){$monthname="May";}
     $NewName = substr(<curname>,16);
     msg MoveTo New folder: . '   ..' . \$year\$season\$day .'-'. $monthname\$NewName;
Of course it would be some time needed to make this script perfect (the $season calculation is not that simple as i has done)

j_c_hallgren
XY Blog Master
Posts: 5826
Joined: 02 Jan 2006 19:34
Location: So. Chatham MA/Clearwater FL
Contact:

Re: Script to Update "Created/Modified Date" Based on File Name

Post by j_c_hallgren »

flavarite wrote:Stefan,
A million thanks!!! :D
Even though this thread doesn't apply to me, but as a fellow forum user, I'd also like to express my thanks to Stefan for your thorough and very helpful replies! Well done! 8)
Still spending WAY TOO much time here! But it's such a pleasure helping XY be a treasure!
(XP on laptop with touchpad and thus NO mouse!) Using latest beta vers when possible.

admin
Site Admin
Posts: 64900
Joined: 22 May 2004 16:48
Location: Win8.1, Win10, Win11, all @100%
Contact:

Re: Script to Update "Created/Modified Date" Based on File Name

Post by admin »

Stefan wrote:Hi flavarite, great it works, thanks for the response.
In future you can make all this work inside XYplorer, if you want :D
Thanks, Stefan, for pointing this out!

Stefan
Posts: 1360
Joined: 18 Nov 2008 21:47
Location: Europe

Re: Script to Update "Created/Modified Date" Based on File Name

Post by Stefan »

No prob, great that i was able to do that ....
thanks to the community who gave me an starting point to scripting :lol:

And of course to Donald too!





 

sfranky
Posts: 30
Joined: 12 Aug 2010 22:15

Re: Script to Update "Created/Modified Date" Based on File Name

Post by sfranky »

guys thanks very much for this script, it's a treasure !!!!!!

HarpoonJoe
Posts: 1
Joined: 25 Jun 2011 03:45

Re: Script to Update "Created/Modified Date" Based on File Name

Post by HarpoonJoe »

Hi folks, I'm new to xyplorer and find myself in a similar position to flavarite. The problem I'm having is that my filenames are structured differently.

The format I have is "2007-11-17 t10-32-50 dv10mac04.avi"
ie date 17th November 2007, time 10.32 and 50 seconds. The rest of the file name is a reference corresponding to which dv tape the video originated from.

I've tried to modify the code suggested (attached below) but without any luck, could someone could help me with the syntax?

Thanks in advance
Paul

Code: Select all

"Set date from filename"
   $filelist = getinfo('SelectedItemsPathNames', '|');
   $count=1;
   while(1){
      $file=gettoken($filelist,$count,"|");
      if("$file"==""){break;}
    
     //your code here
     $RegExFind = ".+_(\d{4})(\d{2})(\d{2})_(\d{2})(\d{2})(\d{2})\..*";
     $RegExReplace = "$1-$2-$3 $4:$5:$6";
     $date = regexreplace("$file", $RegExFind, $RegExReplace);
      timestamp mc, $date, $file;


      $count++;}
   status "Done!",,ready;
   beep 800,100; beep 400,100; beep 600,100;

Stefan
Posts: 1360
Joined: 18 Nov 2008 21:47
Location: Europe

Re: Script to Update "Created/Modified Date" Based on File Name

Post by Stefan »

Hi Paul, welcome to the community!

Let me explain a little more since this seams to be an task of common interest.




According to my editing above there is an slightly new syntax and better commands to build this script
as i have written over there >> http://www.xyplorer.com/xyfc/viewtopic. ... 678#p60678
But I will post it here below again, modified for your example.




That script below can be used for all kind of file names,
only the RegEx (regular expression pattern) has to be adjusted to match the time and date.

I will show here how as an example:

For your string
"2007-11-17 t10-32-50 dv10mac04.avi"
we have to split that into several parts to match the different time and date pattern.

First match start of string by an RegEx meta sign => ^

Then match 4 digit for year => \d\d\d\d
Put that match into parentheses (...) to refer to it later in replacement => (\d\d\d\d) by using $1 there for the first ()-group

match an hyphen literally => -
match two digits => \d\d ==> and store it in group $2 ===> (\d\d)

match an hyphen literally => -
match two digits => \d\d ==> and store it in group $3 ===> (\d\d)

match an blank
match an t
match two digits, hyphen, two digits, hyphen, two digits => (\d\d)-(\d\d)-(\d\d)
match an blank and then the rest of string till end => .+$

Note: things we don't need for replacement we don't match in parentheses because we drop them anyway


So for
"2007-11-17 t10-32-50 dv10mac04.avi"
we build an RegEx like:
^(\d\d\d\d)-(\d\d)-(\d\d) t(\d\d)-(\d\d)-(\d\d) .+$

and our XYplorer string looks like:
$RegExFind = " ";
$RegExFind = "^(\d\d\d\d)-(\d\d)-(\d\d) t(\d\d)-(\d\d)-(\d\d) .+$";



Note that we can shorten that RegEx by using
\d{4}
instead of
\d\d\d\d
and build the regex like
$RegExFind = "^(\d{4})-(\d{2})-(\d{2}) t(\d{2})-(\d{2})-(\d{2}) .+$";
but that looks even more worse and didn't save much.







How to build the $RegExReplace string is depending on your local settings.

Here is an excerpt from the timestamp() help
//add day and month as you need for your local settings:
//timestamp [type], [date], [itemlist]
//type [optional] c|m|a or any combinations in any order (cm, am, cma, ac...); defaults to cma
//date [optional] must be in a format that the local system can understand
//timestamp mc, "<date yyyy-mm-dd> 12:00:00", "C:\Test.txt|C:\Test2.txt"
timestamp mc, "1/1/$date", $file;
Note that "$date" is set into quotes.



So you have to build the $RegExReplace string at your own:


We have matched 6 parts from the file name and hold them into groups, named $1 to $6
$1 will hold the year
$2 the month
$3 the day
$4 the hour
$5 the minutes
$6 the seconds

As $RegExReplace string, for example use something like:
timestamp mc, "$3/$2/$1 $4:$5:$6", $file;
or
timestamp mc, "$1-$2-$3 $4:$5:$6", $file;
or
what ever order match
when you open DOS-Box and type in
date /t <ENTER>
time /t <ENTER>

You see, you can refer to the content matched and stored into ()-groups by $n syntax
and by any order and by adding any new signs as you need.
You can even get an output like: "It was $6 seconds after $4:$5 on $3.$2 of the year $1, as i produced my first million of revenue"





So here is the script with new foreach() command and new syntax like get() instead of getinfo()

Code: Select all

"Set date from filename"

    //////collect the selected files into var $fileslist:   
    $filelist = get('SelectedItemsPathNames', '|');
    
    //////foreach($variable, listoftokens, [separator=|]) 
    foreach( $file, $filelist) {
         
          //////regex to match 
          $RegExFind = "^(\d\d\d\d)-(\d\d)-(\d\d) t(\d\d)-(\d\d)-(\d\d) .+$";
          

          
          //////add day and month as you need for your local settings:
          //////timestamp [type], [date], [itemlist]
          //////type [optional] c|m|a or any combinations in any order (cm, am, cma, ac...); defaults to cma
          //////date [optional] must be in a format that the local system can understand
          //////timestamp mc, "<date yyyy-mm-dd> 12:00:00", "C:\Test.txt|C:\Test2.txt"


          //////replace with what is matched by the pattern inside the parenthesis ()
          $RegExReplace = "$1-$2-$3 $4:$5:$6";
          
          //////execute the regex:
          $date = regexreplace($file, $RegExFind, $RegExReplace);


          //////set new timestamp:
          timestamp mc, "$date", $file;
        
    }
   status "Done!",,ready;
   beep 800,100; beep 400,100; beep 600,100;


or in short

Code: Select all

"Set date from filename"

   ////////////// user settings:
   ////// RegEx to match YYYY-MM-DD tHH-NN-SS out of:  "2007-11-17 t10-32-50 dv10mac04.avi"
   ////// and store into groups named from $1 to $6 from left to right.
   $RegExFind = "^(\d\d\d\d)-(\d\d)-(\d\d) t(\d\d)-(\d\d)-(\d\d) .+$";
   
   ////// RegEx  to build an $DATE in a format that the local system can understand
   ////// by reorder the $n groups:
   $RegExReplace = "$1-$2-$3 $4:$5:$6";


   /////////////code for each selected file:
    foreach( $file, get('SelectedItemsPathNames', '|') ) {
          $DATE = regexreplace($file, $RegExFind, $RegExReplace);
          timestamp mc, "$DATE", $file;
    }


   //////the end, inform the user that it is over:
   status "Renaming done!",,ready;   beep 800,100; beep 400,100; beep 600,100;

- - -

Some explanations:


1.)
Please note that the command getinfo() is officially renamed to get() long ago

2.)
I see that that is not needed anymore:

Code: Select all

    //if var $file is empty break the script:
      if("$file"==""){break;}
because of:
Help wrote:get("SelectedItemsPathNames");
Note that before v9.40.0007 the separator was actually a delimiter (i.e. it was returned after each item, not between the items.
- - -


HTH? :D and i have not mixed things up to much.


-- 850 --

Sloot
Posts: 3
Joined: 20 Jan 2013 04:28

Re: Script to Update "Created/Modified Date" Based on File N

Post by Sloot »

I can't seem to get this script to work for me and I think the problem is with the $RegexFind variable.

My file name format is "I:\Home Video Test\.2005-12-30_08-53-09.00.avi"

I modifed the @RegExFind variable as follows

Code: Select all

$RegExFind = "^(\d\d\d\d)-(\d\d)-(\d\d)_(\d\d)-(\d\d)-(\d\d).+$";
Can anybody tell me if I have done something wrong?

My $date variable ends up being "I:\Home Video Test\.2005-12-30_08-53-09.00.avi", not "2005-12-30 8:53:09" and the timestamp function won't work.

My complete script is as follows:

Code: Select all

"Set date from filename"

    //////collect the selected files into var $fileslist:   
    $filelist = get('SelectedItemsPathNames', '|');
    
    //////foreach($variable, listoftokens, [separator=|]) 
    foreach( $file, $filelist) {
         
          //////regex to match 
          $RegExFind = "^(\d\d\d\d)-(\d\d)-(\d\d)_(\d\d)-(\d\d)-(\d\d).+$";
          

          
          //////add day and month as you need for your local settings:
          //////timestamp [type], [date], [itemlist]
          //////type [optional] c|m|a or any combinations in any order (cm, am, cma, ac...); defaults to cma
          //////date [optional] must be in a format that the local system can understand
          //////timestamp mc, "<date yyyy-mm-dd> 12:00:00", "C:\Test.txt|C:\Test2.txt"


          //////replace with what is matched by the pattern inside the parenthesis ()
          $RegExReplace = "$1-$2-$3 $4:$5:$6";
          
          //////execute the regex:
          $date = regexreplace($file, $RegExFind, $RegExReplace);


          //////set new timestamp:
          timestamp mc, "$date", $file;
        
    }
   status "Done!",,ready;
   beep 800,100; beep 400,100; beep 600,100;

highend
Posts: 14571
Joined: 06 Feb 2011 00:33
Location: Win Server 2022 @100%

Re: Script to Update "Created/Modified Date" Based on File N

Post by highend »

Didn't take a look at your script but
.2005-12-30_08-53-09.00.avi
Won't be matched by
^(\d\d\d\d)-(\d\d)-(\d\d)_(\d\d)-(\d\d)-(\d\d).+$
Because you're missing the dot in front of your filename.

Try
^\.(\d\d\d\d)-(\d\d)-(\d\d)_(\d\d)-(\d\d)-(\d\d).+$
instead.
One of my scripts helped you out? Please donate via Paypal

Sloot
Posts: 3
Joined: 20 Jan 2013 04:28

Re: Script to Update "Created/Modified Date" Based on File N

Post by Sloot »

Thanks for your reply. I had tried adding the "." in front without success but hadn't tried adding the \. as you suggested. I tried that and still couldn't get it to work. This is the script I tried:

Code: Select all

"Set date from filename"

    //////collect the selected files into var $fileslist:   
    $filelist = get('SelectedItemsPathNames', '|');
    
    //////foreach($variable, listoftokens, [separator=|]) 
    foreach( $file, $filelist) {
         
          //////regex to match 
          $RegExFind = "^\.(\d\d\d\d)-(\d\d)-(\d\d)_(\d\d)-(\d\d)-(\d\d).+$";
          

          
          //////add day and month as you need for your local settings:
          //////timestamp [type], [date], [itemlist]
          //////type [optional] c|m|a or any combinations in any order (cm, am, cma, ac...); defaults to cma
          //////date [optional] must be in a format that the local system can understand
          //////timestamp mc, "<date yyyy-mm-dd> 12:00:00", "C:\Test.txt|C:\Test2.txt"


          //////replace with what is matched by the pattern inside the parenthesis ()
          $RegExReplace = "$1-$2-$3 $4:$5:$6";
          
          //////execute the regex:
          $date = regexreplace($file, $RegExFind, $RegExReplace);


          //////set new timestamp:
          timestamp mc, "$date", $file;
        
    }
   status "Done!",,ready;
   beep 800,100; beep 400,100; beep 600,100;

Post Reply