Custom tag (exiftool config) to only use day component of Create Date (not secs)

Started by richardl152, November 30, 2019, 05:14:46 AM

Previous topic - Next topic

richardl152

I am trying to sort photos by subdirectories based on Create Date but whole days only.   No problem to do that except that Create Date and similar also have time as part of the data.  Consequently sub directories are created with day and time which fragments the sort too much. 

Grand plan therefore is to define a custom tag in Exif Config file to make a new tag.    Pseudo code is this:

__________________________________________________

DayOnlyDate =>       {
                                       Require => {
                                               0 => 'CreateDate',
                                               
                                                         },
                                ValueConv => q{
                                          return SOMEFUNCTIONDAYPARTONLY $val[0];
                                          },
                                                },
_________________________________________________


Thats where I get stuck - grateful for how to accomplish a custom tag which is only the date component and not the time part.    Ideally Days but if I can also do one for whole Months, also great.

BTW you can do it easily in bash script but I'd like to use exiftool

___________________

#!/bin/bash                                                                                                                                                                                                                                                                                                                                                                                                               
for x in *.* ; do
  d=$(gstat -c %w "$x"); d=${d%% *};
echo $d

  mkdir -p "$d"
   mv -- "$x" "$d/"
done


_________________________

If you want by whole months,  then substitute after the echo above, all lines up to 'done' with

newd="${d:0:7}"
echo $newd

  mkdir -p "$newd"
   mv -- "$x" "$newd/"
_________________________



As a ps,  any pointers to syntax definitions for other functions I can use within the ValueConv routine gratefully received,  I couldn't locate in the documentation.



Phil Harvey

The -d option will do what you want.  For example:

exiftool "-directory<createdate" -d %Y/%m/%d DIR

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

StarGeek

* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

richardl152

Thanks both.    At the risk of being a nuisance,   can I ask how you can extend ExifTool functionality  to doing a CameraModelName directory and within that generate subdirectories by Year and Month.       I can do both singly,  but its tedious to manually go into each CameraModelName directory and run again for Year/Month.  Is there any way to nest these two commands?

Phil Harvey

Something like this should do what you want:

exiftool -d %Y "-directory<$createdate/${model;}/${createdate#;DateFmt('%m/%d')}" DIR

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

richardl152

wonderful, thanks Phil

At the end,  I used this slight variant

exiftool  -r -d %Y '-directory<$createdate/${model;}/${createdate#;DateFmt("%y/%m")}' .

(on a Mac)   as a function in the .bash_aliases  file

_________

function exiftool_sortcamdaterecursive () {

exiftool  -r -d %Y '-directory<$createdate/${model;}/${createdate#;DateFmt("%y/%m")}' .

}

_____________

richardl152

As a final note to anyone following the same route,   I used these three commands in sequence on Mac terminal.

file_createdateshort_sort ; exiftool_sortdaterecursive ; exiftool_sortcamdaterecursive

to first sort on file create date as recorded in the file information itself (as opposed to the EXIF),  then on date (for when camera type not present in the EXIF),  then camera type with create date both from EXIF.   The recursion goes into any subdirectories arising from the first command  and hoovers up all EXIF based sort possibles.

file_createdateshort_sort  -  a bash script
______

#!/bin/bash                                                                     
for x in *.* ; do
  d=$(gstat -c %w "$x"); d=${d%% *};
newd="${d:0:7}"
echo $newd

  mkdir -p "$newd"
   mv -- "$x" "$newd/"
done

and these are the bash_alias functions for the other two commands
_____

function exiftool_sortdaterecursive () {


exiftool -r   -d %Y '-directory<createdate' -d %Y/%m/%d .

}

______

function exiftool_sortcamdaterecursive () {

exiftool  -r -d %Y '-directory<$createdate/${model;}/${createdate#;DateFmt("%y/%m")}' .

}

______

I hope this helps others sort out photo directories

Richard





Phil Harvey

I think you may still be doing more scripting than necessary.  I don't know what gstat does, but ExifTool returns the filesystem modification date/time as FileModifyDate if that is what you are doing.

Typically one would do this:

exiftool -r -d %Y '-directory<filemodifydate' '-directory<createdate' '-directory<$filemodifydate/${model;}/${filemodifydate#;DateFmt("%y/%m")}' '-directory<$createdate/${model;}/${createdate#;DateFmt("%y/%m")}' DIR

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

richardl152

Phil,   many thanks,   actually the gstat -c %w "$x"  bit is file creation time not file modification   but if there's an option

"-directory<filecreatedate"

then that would be perfect.   I probably am doing more scripting than needed!!    The file_createdateshort_sort.sh script  I had knocking around anyway but a full solution just with exiftool would of course be very efficient.

Richard

Phil Harvey

FileCreateDate is problematic because it is system dependent.  It is available in Windows, and on Mac if the RequestAll API option is set to 2.  Most Unix file systems don't support this.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

richardl152

Phil - many thanks

I added this to my config

%Image::ExifTool::UserDefined::Options = (
    RequestAll => 2,        # request additional tags not normally generated
);


but its giving me an error "Operator or semicolon missing before %Image::ExifTool::UserDefined::Options
Ambiguous use of % resolved as operator % at
Useless use of a constant ("RequestAll") in void context at
Can't modify modulus (%) in scalar assignment

My full working exif config is

%Image::ExifTool::UserDefined = (
                              'Image::ExifTool::Composite' => {

#########
                               XYResolution =>  {
                                       Require => {
                                               0 => 'XResolution',
                                               1 => 'YResolution',
                                                         },
                                ValueConv => q{
                                          return $val[0]*$val[1];
                                          },
                                                },


                                FocusCalc =>    {
                                          Require => {
                                           0 => 'FocalLength',
                                           1 => 'ShutterSpeed',
                                                        },
                                ValueConv => q{
                                          return $val[0]*$val[1];
                                          },
                                                },

#########
                                },

                                );


print "Loading Exiftool completed \n"


#%Image::ExifTool::UserDefined::Options = (
#    RequestAll => 2,        # request additional tags not normally generated
#);
#print "Loading RequestAll \n"

#------------------------------------------------------------------------------


Taking the # from the penultimate 4 lines shows the error, and the print statement also fails.   Grateful for your help to fix.

PH Edit: Put code in code block

Phil Harvey

...where DIR is the name of a directory/folder containing the images.  On Mac/Linux, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

richardl152

(doh!)    sometimes you just get code-blind after a while,   what a mistake to make.....

thanks for patience Phil.