Link to home
Start Free TrialLog in
Avatar of TheDadCoder
TheDadCoder

asked on

Script to sort files by creation date

Hi,

I have tons of family picture files in png/jpg format that I want to sort.  Using a script on the PC I want the script to traverse a given directory structure and moving all files into another path which is a flat directory with only folders with newly moved files, in the folder format name of YYYY MM DD

Source folder:  C:\pictures\picstosort
(This is a folder full of other folders and pics in the root of this folder that needs to be traversed fully)

Destination folder: C:\pictures\library
(Folders in here are in the format YYYY MM DD)


Can anyone write this script for me, i don't have a clue how to do this?

Is this even possible!

Thanks,
Avatar of oBdA
oBdA

Try this batch script; save as Whatever.cmd. It is currently in test mode and will only print the commands it would normally run, without really doing anything, so that yo can test it.
To run it for real, remove the two uppercase ECHOs in lines 14 and 15.
It currently assumes that you have a date format of YYYY/MM/DD; if not, please post the first line of the script's output (where it shows the file date of the files being processed).
@echo off
setlocal enabledelayedexpansion
set SourceRoot=C:\pictures\picstosort
set TargetRoot=C:\pictures\library
set FileMask=*.*
for /r "%SourceRoot%" %%a in (%FileMask%) do (
	echo Processing [%%~ta] %%~fa
	for /f "tokens=1-3 delims=. " %%f in ("%%~ta") do (
		set DD=%%f
		set MM=%%g
		set YYYY=%%h
	)
	set TargetFolder=!YYYY! !MM! !DD!
	if not exist "%TargetRoot%\!TargetFolder!" ECHO md "%TargetRoot%\!TargetFolder!"
	ECHO move "%%~fa" "%TargetRoot%\!TargetFolder!"
)

Open in new window

You may find the easiest thing to do is to do a Search for *.jpg (using the Details view), and then you can move the files to suit yourself.  Flicking to the thumbnails view can often let  you know what you're looking at.

I personally name my photo folders in a REVERSE date format, followed by some explanation ie:
2012-08-31 - Dad's birthday weekend

I don't bother splitting events into individual days, as that often isn't relevant to me.  Naming the dates in reverse order lets them sort more easily.
Avatar of TheDadCoder

ASKER

Hi oBda - thanks for the script.

Here's the requested output, with the echos still in place.

I'm in the UK, but my date format preference is the below purely out of windows explorer auto list, etc.

YYYY MM DD

I've modified the paths to suit my testing, with two sample files, both with different dates.

Processing [13/10/2011 18:22] C:\Users\admin\Downloads\picstosort\050112 001.JPG
md "C:\Users\admin\Downloads\library\ 18:22 13/10/2011"
move "C:\Users\admin\Downloads\picstosort\050112 001.JPG" "C:\Users\admin\Downloads\library\ 18:22 13/10/2011"
Processing [14/10/2011 14:28] C:\Users\admin\Downloads\picstosort\050112 002.JPG
md "C:\Users\admin\Downloads\library\ 14:28 14/10/2011"
move "C:\Users\admin\Downloads\picstosort\050112 002.JPG" "C:\Users\admin\Downloads\library\ 14:28 14/10/2011"

Open in new window


It's keeping the time of the day, can we omit this and use the YYYY-MM-DD folder format?

Thanks so much
Hi DanDh99 - I have upward of 100,000 images, mostly already sorted into YYYY/Month folders, but it's a mess that needs a lot of work.  As i sort more pictures into the library, I find pictures out of place, in the wrong month and even year folder...   so i must have been drunk when i put them in there in the first place!

So I'm looking at a script to just rework the whole folder structure into days, and then I'll move into months and years.

so i end up with :

root:
YYYY

root+1
Months of the year

root+3
Days of the Month

i.e.
2013/October/19

or as it seems the case will be
2013/October/2013-October-19


If i only had a few images, then find a manual approach like i have been doing is fine (15+ years).  But with image sizes increasing and number of images taken it's getting out of control and need a reliable and consistent method.

Thanks for the input though.  (I'm sure I will manually suffix many names to the final level day folder for events, as you mentioned.)
Sorry, my bad. In line 8, the first delim should have been a "/", not a "."; try it like this:
@echo off
setlocal enabledelayedexpansion
set SourceRoot=C:\pictures\picstosort
set TargetRoot=C:\pictures\library
set FileMask=*.*
for /r "%SourceRoot%" %%a in (%FileMask%) do (
	echo Processing [%%~ta] %%~fa
	for /f "tokens=1-3 delims=/ " %%f in ("%%~ta") do (
		set DD=%%f
		set MM=%%g
		set YYYY=%%h
	)
	set TargetFolder=!YYYY!-!MM!-!DD!
	if not exist "%TargetRoot%\!TargetFolder!" ECHO md "%TargetRoot%\!TargetFolder!"
	ECHO move "%%~fa" "%TargetRoot%\!TargetFolder!"
)

Open in new window

Thanks for that, here's the output:

Processing [13/10/2011 18:22] C:\Users\admin\Downloads\picstosort\050112 001.JPG
md "C:\Users\admin\Downloads\library\2011-10-13"
move "C:\Users\admin\Downloads\picstosort\050112 001.JPG" "C:\Users\admin\Downloads\library\2011-10-13"
Processing [14/10/2011 14:28] C:\Users\admin\Downloads\picstosort\050112 002.JPG
md "C:\Users\admin\Downloads\library\2011-10-14"
move "C:\Users\admin\Downloads\picstosort\050112 002.JPG" "C:\Users\admin\Downloads\library\2011-10-14"

Open in new window


This looks good so I'll put some files through it and see it proces them...
Hi oBda, I've run a few hundred files through the code and it does file them according to date.

However, it's not using the correct date.

See screenshot attached.

This image was definitely taken on the 20 December 2011.  However, it was filed into 5 January 2012.

The created date can be ignored at that is today's date, so we're saying when the file was added to disk (?)

The modified date, is the date you're using must be the date that windows(?) set at the time the image file was moved from the camera to the computer.

However, as the screenshot shows there's another date called 'Date' or 'Date taken', which is the date the image was taken, really created.

Are you able to utilise that date instead?
Screen-Shot-2013-10-20-at-11.32..png
Probably yes (though the process might take significantly longer). What you're looking for is a part of the meta data of the file(s) (that may or may not exist, depending on the application/camera that created the picture).
Download ExifTool from http://www.sno.phy.queensu.ca/~phil/exiftool/
Unpack the archive (contains a file "exiftool(-k).exe"), and rename the exe to "exiftool.exe"; put this into the script folder.
Then open a command prompt, enter
cd /d "Y:\our\script\folder"
Now enter
exiftool.exe -*date* -s1 "P:\ath\to\the\screenshot\picture\050112 139.jpg"
(or stop after "-s1 " and drag the file from Explorer into the command prompt to save some typing), and post the output here.
Hi oBda, thanks for that.  Here's the output of that same file from the screenshot:

Test file 1
FileModifyDate                  : 2012:01:05 20:34:34+00:00
FileAccessDate                  : 2013:10:21 21:42:31+01:00
FileCreateDate                  : 2013:10:21 21:42:31+01:00
ModifyDate                      : 2012:01:05 19:34:33
DateTimeOriginal                : 2011:12:20 13:32:18
CreateDate                      : 2011:12:20 13:32:18
DateAcquired                    : 2012:01:05 19:24:19.327

Open in new window


Test file 2
I also performed the same process on another random file, but before I did I checked to see if there was a 'DateTaken' value in windows explorer, as per screenshot.  This file did not, and the output from exiftool is different, missing the createdate variable:

FileModifyDate                  : 2011:10:13 18:22:00+01:00
FileAccessDate                  : 2013:10:21 21:46:52+01:00
FileCreateDate                  : 2013:10:21 21:46:52+01:00

Open in new window


This one the FileModifyDate is the only one if could be correct.  Using your original script, the script filed it into this folder.

Test file 3
I tested another older image file:
FileModifyDate                  : 2008:09:25 15:30:16+01:00
FileAccessDate                  : 2013:10:21 21:51:59+01:00
FileCreateDate                  : 2013:10:21 21:51:59+01:00
ModifyDate                      : 2008:09:25 15:30:08
DateTimeOriginal                : 2008:09:25 15:30:08
CreateDate                      : 2008:09:25 15:30:08

Open in new window


This image file has the CreatedDate and FileModifyDate (odd that they have different seconds!).  Your original script filed this image into folder: '2008-09-25', as expected.

Test file 4
Another file I tested gave this output
FileModifyDate                  : 2009:12:19 19:19:12+00:00
FileAccessDate                  : 2013:10:21 21:56:15+01:00
FileCreateDate                  : 2013:10:21 21:56:15+01:00
DateTimeOriginal                : 2005:04:26 19:38:24
CreateDate                      : 2005:04:26 19:38:24
DateTimeStamp                   : Off
ExtensionCreateDate             : 2003:03:29 17:47:50
ExtensionModifyDate             : 2003:03:29 17:47:50
DateCreated                     : 2005:04:26

Open in new window


The original filing script filed this image into '2009-12-19' folder, where it should have gone into the DateCreated foldername.

Test file 5
The last file I tested going back to 2000:
FileModifyDate                  : 2000:01:25 11:23:26+00:00
FileAccessDate                  : 2013:10:21 22:01:24+01:00
FileCreateDate                  : 2013:10:21 22:01:24+01:00
ModifyDate                      : 2000:01:22 14:41:55
DateTimeOriginal                : 2000:01:22 14:41:55
CreateDate                      : 2000:01:22 14:41:55

Open in new window

This file should have been filed on '2000-01-25', however the filing script filed it on '2000-01-22'.  



Can the filing script try to identify if CreatedDate exist/has a value in metadata, if not then use the original filing script code?

What do you think?

Thanks
ASKER CERTIFIED SOLUTION
Avatar of oBdA
oBdA

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi oBda,

Here's the output to the script. All 5 test files were processed using the correct real date the image was taken.

Processing 'C:\Users\admin\Downloads\picstosort\050112 001.JPG' ...
... using date from File: 13/10/2011 18:22
md "C:\Users\admin\Downloads\library\2011-10-13"
move "C:\Users\admin\Downloads\picstosort\050112 001.JPG" "C:\Users\admin\Downloads\library\2011-10-13"

Processing 'C:\Users\admin\Downloads\picstosort\050112 139.JPG' ...
... using date from Metadata: 2011:12:20
md "C:\Users\admin\Downloads\library\2011-12-20"
move "C:\Users\admin\Downloads\picstosort\050112 139.JPG" "C:\Users\admin\Downloads\library\2011-12-20"

Processing 'C:\Users\admin\Downloads\picstosort\100_1941.JPG' ...
... using date from Metadata: 2005:04:26
md "C:\Users\admin\Downloads\library\2005-04-26"
move "C:\Users\admin\Downloads\picstosort\100_1941.JPG" "C:\Users\admin\Downloads\library\2005-04-26"

Processing 'C:\Users\admin\Downloads\picstosort\DSCF4715.JPG' ...
... using date from Metadata: 2008:09:25
md "C:\Users\admin\Downloads\library\2008-09-25"
move "C:\Users\admin\Downloads\picstosort\DSCF4715.JPG" "C:\Users\admin\Downloads\library\2008-09-25"

Processing 'C:\Users\admin\Downloads\picstosort\Image (19).JPG' ...
... using date from Metadata: 2000:01:22
md "C:\Users\admin\Downloads\library\2000-01-22"
move "C:\Users\admin\Downloads\picstosort\Image (19).JPG" "C:\Users\admin\Downloads\library\2000-01-22"

Open in new window



I removed the echos and it also ran through as expected.

Awesome, thank you.

I'll process through a much larger dataset and will post an update.
Hi oBda - I've processed through a test group of 12,000 jpg files and the majority work fine, as expected.

However, I notice two things.  

1. program works only with jpg, that's no problem I can make another version for png.  infact this is a nice benefit as it allows me to review none-jpg picture files and investigate those separately.

2. I apparently had a camera back in circa 2004-2006 which didn't record any date/time, except from 1/1/2004 00:00, i.e. clock starts ticking after batteries go in, etc. so not RTC built in.    So I have found images that were taken in 2006 and are being filed as 2004.  This is not something the script can help with as the file datestamp is wrong and the meta data is wrong.   Just a note to be aware of i guess.

Other than these I've very happy with the script, cheers.
awesome script, thanks.
Sorry, should have mentioned that: the script should be able to process .png as well, just add it to to the FileMask variable in line 5 (multiple patterns are possible):
set FileMask=*.jpg *.png
Or simply use *.* if you know that there are only pictures in the folders anyway.
ok, thanks - that will be handy to know.
Hi TheDadCoder

I've been watching from the sidelines and knew that you would get excellent suggestions.  I too have used the exiftool.exe program for a variety of things.  I'm just wondering about the images that had the wrong date written to the EXIF data by the cameras.

I remember seeing a couple of command line switches or inbuilt variables that can be used with the actual program command to correct wrong dates, rather than modifying the date from the batch file using some jiggery pokery.  I'm sure it was exiftool.exe that had these additional options, but I have used quite a lot of command line image-related programs.  Perhaps it wasn't the date that was "fixable", but rather to offset the wrong hour when entering or leaving daylight saving time and the camera doesn't update this automatically.

If you are interested in trying to fix the dates, presuming you know the year the photos were taken, then I am sure this is something that is easily achievable.  Exiftool, and a number of other command line image handling programs, can modify EXIF data.   Perhaps a new question would be more appropriate than posting here in a closed question.