Finding the Year value in every possible tag in order to use in if statement.

Started by 10SexyApples, September 08, 2023, 05:51:52 PM

Previous topic - Next topic

10SexyApples

My apologies if this should be obvious  ;D  ... I've tried everything I can think of and read through forum posts for days and just can't seem to work this out.

I have hundreds of thousands of image and video files that I am attempting to finally wrangle in ( none of which should have dates that are earlier than the year 2005 ) but some of which have years like 1903, 1969, 1970 in some of the tags. It varies from file to file which date tag has the weird years ( clearly a result of some earlier system or camera error along the way ) and it isn't possible to go through every file to ascertain which need to be fixed.

I am attempting to search specific directories using an if statement that will look at each and every date related tag in each file and then move any file that has a date tag earlier than 2005 into a directory named FIX.

I have tried to use -time:all or wildcard -*date* references with an if statement but these don't reference all of the relative date fields that I need to check so I finally just tried all of the current ones I am trying to check entered individually, but even then I am doing something wrong. I can get this to list them properly in terminal:

exiftool -d %F -p '$Filename, $DateTimeOriginal, $FileModifyDate, $FileAccessDate, $FileInodeChangeDate, $FileCreateDate, $MDItemContentCreationDate, $MDItemContentCreationDate_Ranking, $MDItemContentModificationDate, $MDItemContentModificationDate_Ranking, $MDItemDateAdded, $MDItemDateAdded_Ranking, $MDItemFSContentChangeDate, $MDItemFSCreationDate, $MDItemInterestingDate_Ranking' .
but when I try to incorporate the above as an if conditional I can't seem to get it to work ...

exiftool -if -d %F -p '$Filename, $DateTimeOriginal, $FileModifyDate, $FileAccessDate, $FileInodeChangeDate, $FileCreateDate, $MDItemContentCreationDate, $MDItemContentCreationDate_Ranking, $MDItemContentModificationDate, $MDItemContentModificationDate_Ranking, $MDItemDateAdded, $MDItemDateAdded_Ranking, $MDItemFSContentChangeDate, $MDItemFSCreationDate, $MDItemInterestingDate_Ranking lt "2005:01:01" ' -directory=/path/to/new/directory /path/to/source/files/
So, I'm pretty exasperated at this point, as this was only the final in a long list of my futile attempts to pull this off, and I'm hoping someone on here can point me in the right direction once and for all ;-)

exiftool is such an incredible and powerful bit of coding and I just continue to be amazed by it. Hats off and huge thanks to Phil Harvey!!!

StarGeek

The -p (-printFormat) option is not an if statement.  Any conditions to check for must immediately follow the -if option and is completely separate from the -p option.  In this case, you are checking for -if -d, which will always fail.

If you want to check all of those tags on the command line, then you have to check each item as part of the condition.

Additionally, if any one of those tags doesn't exist, exiftool will return a Tag not defined warning.
C:\>exiftool -time:all --system:all -G -a -s y:\!temp\Test4.jpg
[EXIF]          DateTimeOriginal                : 2004:01:01 12:00:00
[EXIF]          CreateDate                      : 2023:09:09 12:00:00

C:\>exiftool -if "$DateTimeOriginal lt '2005:01:01' or $CreateDate lt '2005:01:01' or $ModifyDate lt '2005:01:01'" -p "$DateTimeOriginal, $CreateDate, $ModifyDate" y:\!temp\Test4.jpg
Warning: [Minor] Tag 'ModifyDate' not defined - y:/!temp/Test4.jpg

To work around the warning, you would have to use either the -m (-ignoreMinorErrors) option or the -f (-ForcePrint) option.  But when the -m option is used, the value defaults to an empty string, which will always be less than everything else.  The -f option defaults to a hyphen -, which will be less than any number.

Luckily, the -f character can be changed with the -api MissingTagValue option.

In this example, I set the MissingTagValue value to "z", which will always be greater than any number
C:\>exiftool -time:all --system:all -G -a -s y:\!temp\Test4.jpg
[EXIF]          DateTimeOriginal                : 2004:01:01 12:00:00
[EXIF]          CreateDate                      : 2023:09:09 12:00:00

C:\>exiftool -api "MissingTagValue=z" -if "$DateTimeOriginal lt '2005:01:01' or $CreateDate lt '2005:01:01' or $ModifyDate lt '2005:01:01'" -p "$DateTimeOriginal, $CreateDate, $ModifyDate" y:\!temp\Test4.jpg
2004:01:01 12:00:00, 2023:09:09 12:00:00, z

But to be honest, at this point you are better off creating a user defined tag that will do all the checking and return a true or false.  The basic idea would be similar to the config file in this post, except you would change Require into Desire and then list all the tags in the same manner as the PhysicalImageSize tag in the example config file.
* 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).

10SexyApples

You are a lifesaver! I've been checking back here hourly haha! Thank you so much for the assistance, it is much appreciated! I will begin looking at the example of how to create and use my own config file to ease this process, but in the interim as I'm not entirely sure just how many of these fields and which I will need to include in a config function, I changed my quick code using your advice and would really love if you could just take a look and tell me if you think this would work or if I've screwed the pooch yet again? I'm on a mac terminal so hopefully I've adjusted the single and double quotes appropriately ...

exiftool -api 'MissingTagValue=z' -if '$DateTimeOriginal, $FileModifyDate, $FileAccessDate, $FileInodeChangeDate, $FileCreateDate, $MDItemContentCreationDate, $MDItemContentCreationDate_Ranking, $MDItemContentModificationDate, $MDItemContentModificationDate_Ranking, $MDItemDateAdded, $MDItemDateAdded_Ranking, $MDItemFSContentChangeDate, $MDItemFSCreationDate, $MDItemInterestingDate_Ranking lt "2005:01:01" ' -directory=/path/to/new/directory /path/to/source/files/

10SexyApples

Actually with some testing and applying a tad more common coding sense, I see that what I have written simply checks that those tags exist, not what their value is when written that way. I was trying to at least prevent having to state the conditional "less than" with each tag individually but I have no idea what syntax to use here in order to list an array of tags to check ... guessing that would have to happen in the custom config file?

10SexyApples

Okay, taking a stab at the custom config file. It has been a very long time since I've done any coding and I was amateur at best in my prime so here is what I have come up with for my config file.

#------------------------------------------------------------------------------
# File:         ExifTool_config
#
# Description:  User defined configuration file for Image::ExifTool
#
# Notes:        To activate this file, rename it to ".ExifTool_config" and
#               place it in your home directory or the exiftool application
#               directory.  (On Mac and some Windows systems this must be done
#               via the command line since the GUI's may not allow filenames to
#               begin with a dot.  Use the "rename" command in Windows or "mv"
#               on the Mac.)  This causes ExifTool to automatically load the
#               file when run.  Your home directory is determined by the first
#               defined of the following environment variables:
#
#                   1.  EXIFTOOL_HOME
#                   2.  HOME
#                   3.  HOMEDRIVE + HOMEPATH
#                   4.  (the current directory)
#
#               Alternatively, the -config option of the exiftool application
#               may be used to load a specific configuration file (note that
#               this must be the first option on the command line):
#
#                   exiftool -config example.config ...
#
#------------------------------------------------------------------------------

# Shortcut tags are used when extracting information to simplify
# commonly used commands.  They can be used to represent groups
# of tags, or to provide an alias for a tag name.
#%Image::ExifTool::UserDefined::Shortcuts = (
#    MyShortcut => ['exif:createdate','exposuretime','aperture'],
#    MyAlias => 'FocalLengthIn35mmFormat',
#);

# NOTE: All tag names used in the following tables are case sensitive.

# The %Image::ExifTool::UserDefined hash defines new tags to be added
# to existing tables.
%Image::ExifTool::UserDefined = (

    # Composite tags are added to the Composite table:
    'Image::ExifTool::Composite' => {
        # Composite tags have values that are derived from the values of
        # other tags.  The Require/Desire elements below specify constituent
        # tags that must/may exist, and the keys of these hashes are used as
        # indices in the @val array of the ValueConv expression to access the
        # numerical (-n) values of these tags.  Print-converted values are
        # accessed via the @prt array.  All Require'd tags must exist for
        # the Composite tag to be evaluated.  If no Require'd tags are
        # specified, then at least one of the Desire'd tags must exist.  See
        # the Composite table in Image::ExifTool::Exif for more examples,
        # and lib/Image/ExifTool/README for all of the details.
        # the next few examples demonstrate simplifications which may be
        # used if only one tag is Require'd or Desire'd:
        # 1) the Require lookup may be replaced with a simple tag name
        # 2) "$val" may be used to represent "$val[0]" in the expression

        # List all possible date tags in order to evaluate if any are prior to a specified date
        CheckAllDates => {
            Desire => {
0 => 'FileModifyDate',
1 => 'FileAccessDate',
2 => 'FileInodeChangeDate',
3 => 'FileCreateDate',
4 => 'MDItemContentCreationDate',
5 => 'MDItemContentCreationDate_Ranking',
6 => 'MDItemContentModificationDate',
7 => 'MDItemContentModificationDate_Ranking',
8 => 'MDItemDateAdded',
9 => 'MDItemDateAdded_Ranking',
10 => 'MDItemFSContentChangeDate',
11 => 'MDItemFSCreationDate',
12 => 'MDItemInterestingDate_Ranking',
13 => 'MDItemLastUsedDate',
14 => 'MDItemLastUsedDate_Ranking',
15 => 'MDItemUsedDates',
16 => 'XAttrLastUsedDate',
17 => 'PreviewDate',
18 => 'CreateDate',
19 => 'ModifyDate',
20 => 'TrackCreateDate',
21 => 'TrackModifyDate',
22 => 'MediaCreateDate',
23 => 'MediaModifyDate',
24 => 'DateTimeOriginal',
            },
            ValueConv => '$val[0]/$val[2] . " " . $val[1]/$val[3]',
            # (the @prt array contains print-formatted values)
            PrintConv => 'sprintf("%.1fx%.1f $prt[4]", split(" ",$val))',
        },
    },
);

# Change default location for writing QuickTime tags so Keys is preferred
# (by default, the PREFERRED levels are: ItemList=2, UserData=1, Keys=0)
#use Image::ExifTool::QuickTime;
#$Image::ExifTool::QuickTime::Keys{PREFERRED} = 3;

# Specify default ExifTool option values
# (see the Options function documentation for available options)
%Image::ExifTool::UserDefined::Options = (
    #CoordFormat => '%.6f',  # change default GPS coordinate format
    Duplicates => 1,        # make -a default for the exiftool app
    #GeoMaxHDOP => 4,        # ignore GPS fixes with HDOP > 4
    RequestAll => 3,        # request additional tags not normally generated
);

#------------------------------------------------------------------------------
1;  #end

And now to actually use it ( if I even did the above correctly that is ) ...

#Find files where any date is earlier than 2005
exiftool -api 'MissingTagValue=z' -if '$CheckAllDates lt "2005:01:01"' -directory=/path/to/new/directory /path/to/source/files/

10SexyApples

I'm just going forward with documenting my progress here in the hopes that it helps others. So, the above solution will work until getting to a directory full of AVI files, at which time the following addition needs to be made.

exiftool -ext+ AVI -api 'MissingTagValue=z' -if '$CheckAllDates lt "2005:01:01"' -directory=/path/to/new/directory /path/to/source/files/
Tested on AVI files known to have the errant 60s and 70s dates thrown in and all were recognized and moved.

Now I just need to expand on this since I've made the config file and have it actually list out in the terminal a nicely formatted list that shows the filename - the offending tag - the offending date. Ha. I can dream ;-)

StarGeek

Quote from: 10SexyApples on September 09, 2023, 04:41:19 PMI've been checking back here hourly haha!

I don't have time at the moment to look over your posts, but with regards to this, change the "No alerts or emails" setting on this thread
* 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).