Page 1 of 2

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

Posted: 05 Jun 2010 17:26
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;

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

Posted: 05 Jun 2010 18:09
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

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

Posted: 06 Jun 2010 09:40
by admin
Just a little remark: There's no need to put "$file" in quotes.

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

Posted: 06 Jun 2010 10:41
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.)

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

Posted: 07 Jun 2010 01:19
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;

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

Posted: 07 Jun 2010 08:30
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)

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

Posted: 07 Jun 2010 08:49
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)

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

Posted: 07 Jun 2010 09:00
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!

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

Posted: 07 Jun 2010 10:48
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!





 

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

Posted: 16 May 2011 11:33
by sfranky
guys thanks very much for this script, it's a treasure !!!!!!

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

Posted: 25 Jun 2011 04:00
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;

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

Posted: 25 Jun 2011 13:06
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 --

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

Posted: 20 Jan 2013 04:42
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;

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

Posted: 20 Jan 2013 18:07
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.

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

Posted: 20 Jan 2013 19:28
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;