IFs and empty tags

Started by RAC, June 09, 2010, 02:10:02 PM

Previous topic - Next topic

RAC

Hiya,

I'm using a non-digital lens on a digital camera and thus the camera is not filling-in the lens information in the EXIF. So what I'd like to do is to write that lens information into the EXIF, but only on files where no other lens info has been filled-in by the camera.

So what I have is an IF statement follwed by a load of WriteTags. But.. what do I put in the IF statement?

How should I phrase the IF ststement for tags that are shown as 'None'? And for tags that are shown as empty?
-if not $LensID          doesn't work.
-if not $LensType      doesn't work.
-if $LensType equ ''    doesn't work.

Any idea how I can phrase the IF to find empty or 'None' tags please?

Thanks
RAC


Phil Harvey

Are you on Windows or Mac/Unix?

The -if argument requires double quotes on Windows and single quotes on Mac.

ie, for Windows: -if "not $lensID and not $lensType"

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

RAC

Hi Phil,

Thanks for the reply. I should have said that I'm using an args-file, to make life easier.

So within the args-file, I have...

-if
not $LensType

or

-if
$LensType equ 'None'

or

-if
$LensType equ ''

(or the $LensID equivalents of the above).

But NONE of these pick up the files that they should. I can run ExifTool on various files to report $LensType and $LensID as 'None', but when I try to get ExifTool to select files using the IFs above, it won't. So, how can I ask ExifTool to select files where 'None' is being reported?

Thanks,
RAC

Phil Harvey

Very odd.  I can't see what you are doing wrong (unless you are using a really old version of ExifTool!).  Here is a cut-n-paste from a console session for me (on Mac, but Linux would be the same):

> ./exiftool a.jpg b.jpg c.jpg -lenstype
======== a.jpg
Lens Type                       : None
======== b.jpg
======== c.jpg
Lens Type                       : smc PENTAX-DA 21mm F3.2 AL Limited
    3 image files read

> cat t1.args
-if
$lenstype eq 'None'

> ./exiftool a.jpg b.jpg c.jpg -filename -@ t1.args
======== a.jpg
File Name                       : a.jpg
    2 files failed condition

> cat t2.args
-if
not $lenstype

> ./exiftool a.jpg b.jpg c.jpg -filename -@ t2.args
======== b.jpg
File Name                       : b.jpg
    2 files failed condition

> cat t3.args
-if
not $lenstype or $lenstype eq 'None'

> ./exiftool a.jpg b.jpg c.jpg -filename -@ t3.args
======== a.jpg
File Name                       : a.jpg
======== b.jpg
File Name                       : b.jpg
    1 files failed condition
    2 image files read


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

RAC

Hi Phil,

Got it!

Thanks to your reply, I noticed a really subtle difference in syntax - I was using "equ" as per some example documentation, but you used "eq".
So I tried "eq 'None'", and it worked - YEEHAAA!

Mucho thanks for your help here, (and much thanks for this superb tool),
Best,
RAC

Phil Harvey

Right.  I should have noticed that.  That doesn't explain why the "not $lenstype" didn't work.

But glad it works now.

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

ryerman

Hi Phil,

     I was hoping to use the "-if" option to determine if a tag exists.  I create a composite tag that may or may not exist, depending on the filename, and would like to proceed in different ways, depending on its existence.  I've tried
exiftool -if "not $tagname"  -XpTitle file.jpg and
exiftool -if "$tagname"  -XpTitle file.jpg but if the tag does not exist the result is always
    1 files failed condition
     I guess the option always fails if the tag is non-existent.  Is there some refinement to identify missing tags or some other method?

Jim
Windows 10 Home 64 bit, Exiftool v12.61

Phil Harvey

Hi Jim,

Again, I am puzzled.  Here is an excerpt from my Mac Terminal:


> exiftool a.jpg -if 'not $tagname' -XpTitle
XP Title                        : test

> exiftool a.jpg -if '$tagname' -XpTitle
    1 files failed condition


Assuming you are on Windows your double quotes are correct (single quotes are used in Mac and Linux).  Logically, $tagName is false if

a) it doesn't exist
b) it is empty ("")
c) is is zero ("0")

Are you sure the tag doesn't exist?  Try a random tag name to be sure.

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

ryerman

#8
Hi Phil,

I did as you suggested and tried a random tag (I'm pretty sure abcdfg is not a bona fide tag!) and presto!.. things worked as logic dictates.  However, for my particular tag, things are still illogical.  I'd like to emphasize that my tag (AlbumArtType) is a composite.  And also, doesn't it make sense to expect a different result when using -if "not $tagname" than when using -if "$tagname", whether the tag exists or not?  Here's the post I was planning to send before I second guessed myself.

EDIT: I just tried -if "$AlbumArtType eq ''" and -if "$AlbumArtType ne ''" on the file I believe does not have the AlbumArtType tag and received the 2 opposite results.  This is even more puzzling and annoying, given your statement that empty and non-existent are logically equivalent!

Original (unsent) post:
I am also puzzled by the results given by -if "not $sometag".

I have a composite tag called AlbumArtType that may or may not be created, depending on FileName.
If it is created,
exiftool -k -if "not $AlbumArtType" -filename "C:\cover-with AlbumArtType.jpg"
returns
   1 files failed condition
which is correct.

exiftool -k -if "$AlbumArtType" -filename "C:\cover-with AlbumArtType.jpg"
returns
File Name                       : cover-with AlbumArtType.jpg
which is correct.

I know AlbumArtType exists because it appears as the last entry under ----Composite----
when I run exiftool -k -a -u -g1 "C:\cover-with AlbumArtType.jpg"
---- ExifTool ----
ExifTool Version Number         : 8.22
---- System ----
File Name                       : cover-with AlbumArtType.jpg
Directory                       : C:/
File Size                       : 26 kB
File Modification Date/Time     : 2010:03:26 12:04:40-04:00
File Permissions                : rw-rw-rw-
---- File ----
File Type                       : JPEG
MIME Type                       : image/jpeg
Exif Byte Order                 : Big-endian (Motorola, MM)
Image Width                     : 591
Image Height                    : 600
Encoding Process                : Baseline DCT, Huffman coding
Bits Per Sample                 : 8
Color Components                : 3
Y Cb Cr Sub Sampling            : YCbCr4:2:0 (2 2)
---- IFD0 ----
X Resolution                    : 72
Y Resolution                    : 72
Resolution Unit                 : inches
Host Computer                   : Human Conflict Number Five (EP)
Y Cb Cr Positioning             : Centered
XP Title                        : cover-Human Conflict Number Five
XP Author                       : 10,000 Maniacs
XP Keywords                     : Artist:  10 000 Maniacs,Album:  Human Conflict Number Five (EP),Year:  1982
XP Subject                      : Album Art
---- ExifIFD ----
Exif Version                    : 0220
Components Configuration        : Y, Cb, Cr, -
User Comment                    : 1982
Flashpix Version                : 0100
Color Space                     : Uncalibrated
---- Composite ----
Base Name                       : cover-with AlbumArtType
File Extension                  : jpg
File Type Description           : Joint Photographic Experts Group
Fix Album                       : Human Conflict Number Five (EP)
Fix Album 1                     : Human Conflict Number Five (EP)
Fix Album 2                     : Human Conflict Number Five (EP)
Fix Artist                      : 10 000 Maniacs
Fix Artist 1                    : 10 000 Maniacs
Fix Artist 2                    : 10 000 Maniacs
Hold                            : cover*with AlbumArtType.jpg
Image Size                      : 591x600
Album Art Type                  : cover


All of that seems to show that things are working as they should.  However, if AlbumArtType is not created
exiftool -k -if "$AlbumArtType" -filename "C:\without AlbumArtType.jpg"
returns
   1 files failed condition
which is correct, but

exiftool -k -if "not $AlbumArtType" -filename "C:\without AlbumArtType.jpg"
also returns
   1 files failed condition
which is not correct.

I'm pretty sure AlbumArtType does not exist because it is not listed.
exiftool -k -a -u -g1 "C:\without AlbumArtType.jpg" returns
---- ExifTool ----
ExifTool Version Number         : 8.22
---- System ----
File Name                       : without AlbumArtType.jpg
Directory                       : C:/
File Size                       : 6.9 kB
File Modification Date/Time     : 2010:03:26 12:04:44-04:00
File Permissions                : rw-rw-rw-
---- File ----
File Type                       : JPEG
MIME Type                       : image/jpeg
Exif Byte Order                 : Big-endian (Motorola, MM)
Image Width                     : 200
Image Height                    : 200
Encoding Process                : Baseline DCT, Huffman coding
Bits Per Sample                 : 8
Color Components                : 3
Y Cb Cr Sub Sampling            : YCbCr4:2:0 (2 2)
---- IFD0 ----
X Resolution                    : 72
Y Resolution                    : 72
Resolution Unit                 : inches
Host Computer                   : Human Conflict Number Five (EP)
Y Cb Cr Positioning             : Centered
XP Title                        : Human Conflict Number Five
XP Author                       : 10,000 Maniacs
XP Keywords                     : Artist:  10 000 Maniacs,Album:  Human Conflict Number Five (EP),Year:  1982
XP Subject                      : Album Art
---- ExifIFD ----
Exif Version                    : 0220
Components Configuration        : Y, Cb, Cr, -
User Comment                    : 1982
Flashpix Version                : 0100
Color Space                     : Uncalibrated
---- Composite ----
Base Name                       : without AlbumArtType
File Extension                  : jpg
File Type Description           : Joint Photographic Experts Group
Fix Album                       : Human Conflict Number Five (EP)
Fix Album 1                     : Human Conflict Number Five (EP)
Fix Album 2                     : Human Conflict Number Five (EP)
Fix Artist                      : 10 000 Maniacs
Fix Artist 1                    : 10 000 Maniacs
Fix Artist 2                    : 10 000 Maniacs
Hold                            : without AlbumArtType.jpg
Image Size                      : 200x200


Getting the same result to the last 2 logically opposite "-if" options seems wrong to me, but maybe that happens when the syntax or form is incorrect.  I tried various arrangements of single quotes within the double quotes but couldn't get the result I expected.  Is the fact that it is a composite tag important?

Please help me resolve this issue. I use Windows Vista and ExifTool 8.22

Jim


Windows 10 Home 64 bit, Exiftool v12.61

Phil Harvey

I'm getting closer to having all the details I need (I now know your system and ExifTool version).  But the one piece I am missing is your Composite tag definition.  With this I should be able to reproduce your problem.

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

ryerman

Here you go: (I copied these from the 'Image::ExifTool::Composite' section of my Config file)

        # The tag "Hold" contains the desired Album Art type, followed by "*" (and the rest of the filename, if any remains after the substitutions shown)
        # If no substitution is made then "Hold" does not include "*", but just the original filename (where "*" never exists because it is forbidden by Windows) 

        Hold => {
            Require => {
                0 => 'FileName',
                       },

            ValueConv => q{
                        $val =~ s/cover-/cover*/g;
                        $val =~ s/back-/back*/g;
                        $val =~ s/folder-/folder*/g;
                        $val =~ s/photo-/photo*/g;
                        $val =~ s/folder.jpg/covercopy*/g;
                        return $val;
                          },
                },

        # AlbumArtType, a tag to record Album Art type (cover, back, folder, photo, or covercopy)
        # by saving only the portion of the tag "Hold" preceding "*"
        # AlbumArtType = '' (empty) if there is no prefix (ie. the file is a trackcover) although I thought it would be non-existent.  It doesn't appear in the tag list for the files where "Hold" = "FileName" (ie. no substitution was made)
 
       AlbumArtType => {
              Require => {
             0 => 'Hold',
                        },
       # remove everything after "*"
            ValueConv => q{
                         $val =~ /([^\*]*)\*/; $1,
                         },
                      },


As an example, a file named "cover-abc.jpg" will have AlbumArtType = cover but a file named "abc.jpg" will not have the tag AlbumArtType. (not listed, at least)

Thanks for your continuing prompt attention,

Jim
Windows 10 Home 64 bit, Exiftool v12.61

Phil Harvey

Ah, thanks.  Now I understand.

You have fallen prey to a subtle "feature" of Composite tags.  This is related to the problem mentioned in the ValueConv documentation in lib/Image/ExifTool/README of the full distribution (I don't normally suggest people read this file because it contains much more detail than most people need):

                  " The return value should always be defined -- use
                  RawConv instead to return undef if it is necessary to test the
                  value for validity, otherwise an undef tag may hide a
                  previously defined value when the Duplicates option is not
                  enabled."


To fix this, change the ValueConv to RawConv in your Composite tag definition if it is possible for an undefined value to be returned (as with your AlbumArtType).  The RawConv is evaluated at extraction time, and ValueConv is evaluated later when the tag value is requested, at a point where it is assumed the tag exists. 

Also, I will think about this more and see if there is some way I can prevent it from cause similar confusion in the future.

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

Phil Harvey

I think I was wrong, although my solution seemed to fix the problem.   I still didn't understand why adding a logical "not" to your condition didn't change the result, so I spent some more time and traced through the code to figure it out.

It turns out that your ValueConv wasn't returning undef as I had expected.  Instead, the value of $1 comes from the previous expression in my code if your expression doesn't match.  To fix this, I changed your ValueConv to:

    ValueConv => q{ $val =~ /([^\*]*)\*/ ? $1 : undef },

and the problem was solved.  This now returns undef if the expression doesn't match, which may have been what you intended.

The tip about ValueConv hiding other same-named tags if it returns undef is still valid, but it turned out to be unrelated to this problem after all.

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

ryerman

Bingo! That gives the tag value as expected.  I'm glad RawConv wasn't needed, considering the documentation's warning to avoid it's use, and especially because I don't really understand what I'm doing with conversions and substitutions.  It actually made things worse.

I modified your suggested ValueConv to:
   ValueConv => q{ $val =~ /([^\*]*)\*/ ? $1 : "trackcover" },
which gives a specific value to the AlbumArtType tag for every file.

That was what I wanted all along but I couldn't come up with a satisfactory ValueConv statement.  I was willing to settle for what I thought was an undefined tag.  When the "if/if not" logic didn't make sense I reached out for help.

My modification to your ValueConv was a lucky guess, which, combined with lots of trial and error, is my modus operandi when adding to the Config file.  I'd like to find some manual that explains the syntax and commands for substitutions.  Maybe that's the subject for a new thread after I've done more research.

Anyhow, thanks again for your help.  Bertrand Russell can stop turning in his grave. :)
BTW, this forum is great and a huge improvement.

Jim
Windows 10 Home 64 bit, Exiftool v12.61

Phil Harvey

Hi Jim,

Glad that solved it.

To learn more about the syntax of the -if expression, read about the Perl programming language.  Particularly, regular expressions (the "~=" operator) are very useful.

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