ExifTool Forum

ExifTool => The "exiftool" Application => Topic started by: alanterra on August 09, 2020, 08:19:04 PM

Title: Can I read field from raw if not in xmp in one line?
Post by: alanterra on August 09, 2020, 08:19:04 PM
I think the answer to my question is No, (see https://exiftool.org/forum/index.php?topic=6807.0), but I want to confirm.

Adobe products seem to use the algorithm "look in the side car, and if the field isn't there, then look in the raw file." It would be useful to be able to do the same with one command line expression with exiftool. I tried

exiftool -field -srcfile %d%f.xmp -srcfile @ rawfile

but this doesn't work because if the xmp file exists, and the field is not in the xmp file, then exiftool doesn't go on to look at the raw file.

Is there any way to look in one file, and if not found, then in the next?
Title: Re: Can I read field from raw if not in xmp in one line?
Post by: Phil Harvey on August 09, 2020, 09:22:10 PM
How about this?:

exiftool -field -if "defined $field and End()" SIDECAR RAWFILE

Add -q -q to skip the informational messages.

- Phil
Title: Re: Can I read field from raw if not in xmp in one line?
Post by: alanterra on August 10, 2020, 12:34:21 PM
Sorry, I can't make that work (using bash under MacOS 10.14.6). I wasn't clear which of the two variants below you were suggesting, but both give error messages

$ exiftool -canonmodelid -if "defined $canonmodelid and END()" -srcfile %d%f.xmp -srcfile @ "2013-07-17 15-29-18 IMG_5354".CR2
    1 files failed condition
$ exiftool -canonmodelid -if "defined $canonmodelid and END()" "2013-07-17 15-29-18 IMG_5354.xmp" "2013-07-17 15-29-18 IMG_5354.CR2"
    2 files failed condition

And the problem with the second form (which I think you intended) is that I was hoping to find a command that did the following: "if there is an xmp, then look for the field first in the xmp, otherwise in the base file, but if no xmp, then just look in the base file."
Obviously, this is easy with an if statement in Bash, I was just hoping for a one-liner-fits-all solution.

EDIT: If I get rid of the "and END()" then the second variant does give me what I want, but, as I mentioned it fails when there is no sidecar file:

$ exiftool -s3 -q -q -canonmodelid -if "defined $canonmodelid" "2013-07-17 15-29-18 IMG_5354.xmp" "2013-07-17 15-29-18 IMG_5354.CR2"
EOS 5D Mark II
Title: Re: Can I read field from raw if not in xmp in one line?
Post by: StarGeek on August 10, 2020, 02:04:27 PM
Quote from: alanterra on August 10, 2020, 12:34:21 PM
(using bash under MacOS 10.14.6).

Take note of the text at the bottom of Phil's post. 
Title: Re: Can I read field from raw if not in xmp in one line?
Post by: alanterra on August 10, 2020, 04:37:02 PM
Thank you, StarGeek. I didn't quite get what that text was saying when I looked at it. Somehow I had also introduced another error—typing "END()" instead of "End()". I can now get the results that I want in every case except when the field is missing from the sidecar.

Sorry for the long bit of code here, but I think it is necessary to explain what works and what doesn't.

There are two variants of this call, name the sidecar and raw files directly, which only works when there is a sidecar file, and use the "-srcfile" flags which is supposd to work even if the side car is missing. All the variants below get the expected value, with the exception of when I use the "-srcfile" flags, the sidecar file exists, but it doesn't have the field. In this case, for some reason, exiftool doesn't go on to the raw file to look for the field.

I'm stumped.


$ exiftool -lensmodel photo.CR2  # the raw file has a value of 100mm
Lens Model                      : 100mm
$ exiftool -lensmodel=100+ photo.xmp # we give the sidecar file a different value
    1 image files updated
$ exiftool -lensmodel -if 'defined $lensmodel and End()' photo.xmp photo.CR2 # this works, gets the value from the sidecar
======== photo.xmp
Lens Model                      : 100+
End called - photo.xmp
$ exiftool -lensmodel -if 'defined $lensmodel and End()' photo.CR2 photo.xmp # this works, reverse the order of arguments, gets value from raw file
======== photo.CR2
Lens Model                      : 100mm
End called - photo.CR2
$ exiftool -lensmodel -if 'defined $lensmodel and End()' -srcfile %d%f.xmp -srcfile @ photo.CR2 # it also works with -srcfile flags, but note that "End called" is different than two commands above?
Lens Model                      : 100+
End called - photo.CR2
$ exiftool -lensmodel -if 'defined $lensmodel and End()' -srcfile @ -srcfile %d%f.xmp photo.CR2 # reversing order of files
Lens Model                      : 100mm
End called - photo.CR2
$ exiftool -lensmodel= photo.xmp # Now let's delete the field from the sidecar
    1 image files updated
$ exiftool -lensmodel -if 'defined $lensmodel and End()' photo.xmp photo.CR2 # and we get the value in the raw file
======== photo.CR2
Lens Model                      : 100mm
End called - photo.CR2
    1 files failed condition
$ exiftool -lensmodel -if 'defined $lensmodel and End()' -srcfile %d%f.xmp -srcfile @ photo.CR2 # but the variant using -srcfile doesn't work!
    1 files failed condition
$ mv photo.xml photo1.xml # hide the sidecar file
$ exiftool -lensmodel -if 'defined $lensmodel and End()' -srcfile %d%f.xmp -srcfile @ photo.CR2 # and it works
Lens Model                      : 100mm
End called - photo.CR2
$
Title: Re: Can I read field from raw if not in xmp in one line?
Post by: Phil Harvey on August 10, 2020, 06:49:04 PM
I wasn't using the -srcfile option.  My solution just stops processing after it finds a file that satisfies the -if condition (no -srcfile option).

- Phil
Title: Re: Can I read field from raw if not in xmp in one line?
Post by: alanterra on August 11, 2020, 12:08:04 PM
Phil -- I think it would be very useful for those of us who use sidecars to be able to use exiftool in a way that mirrors how Adobe uses them:

when reading a tag: if there is a sidecar file, look there for the tag; if not found or no sidecar, then look in the main (raw) file.
when writing a tag: if there is a sidecar, write to the sidecar, if no sidecar and the file is a raw file, create the sidecar then write to it, otherwise write to the main file

Right now, when I write scripts to manipulate a number of files I have to write code that tries to implement the above. But I don't know if my needs are a special case, or if it is a common use-case.

Thanks for exiftools. I use it all the time.
Title: Re: Can I read field from raw if not in xmp in one line?
Post by: StarGeek on August 11, 2020, 02:26:57 PM
From what I read here over the years, the would probably require a complete rewrite of the way exiftool works, though Phil would have to comment on that.

But it leads to the additional question, What type of sidecar file?  There are multiple possible sidecar files other than XMP.  Exiftool can also write XML, EXIF, EXV, and it's own MIE sidecar files (see Metadata Sidecar Files (https://exiftool.org/metafiles.html)).  And if I recall correctly, THM files are also considered sidecar files.
Title: Re: Can I read field from raw if not in xmp in one line?
Post by: Phil Harvey on August 11, 2020, 03:05:06 PM
It should be fairly easy to whip up a Perl script to do exactly what you want using the ExifTool API.  That is if you know Perl.

- Phil
Title: Re: Can I read field from raw if not in xmp in one line?
Post by: alanterra on August 11, 2020, 03:09:54 PM
Yeah, I don't. I'm in the process of teaching myself Python, and that is all this aging brain can do at one time. Thanks.