Problem executing ExifTool from within my Mac app

Started by Joanna Carter, March 20, 2021, 07:24:23 AM

Previous topic - Next topic

Joanna Carter

I have been using ExifTool from within my Mac app for several years now but now I come to add a new feature and am having problems getting the arguments to send to the process correct.

I want to conditionally add or remove one keyword from the xmp:Subject tag

Here is the command I think I am sending

exiftool -if '$xmp:Subject =~ "Drill"' -xmp:Subject-=Drill filename.ext


The error the is being propagated back to the debugger is Warning: Sorry, if '$xmp:Subject doesn't exist or isn't writable Nothing to do.

If I paste this line into the macOS terminal, it works fine.

I'm obviously missing something subtle here as the line works fine from my app without the -if condition

Joanna Carter

#1
I have found if I put the -if after the command...


exiftool -xmp:Subject-=Drill -if '$xmp:Subject =~ "Drill"' filename.ext


... I no longer get the error message but the command doesn't have any effect either

Although I now realise that I don't need the condition for the -= or the += operator, I am interested to know why I might be getting this problem when I do try to use the -if tag?

Phil Harvey

This is what I get in a Mac Terminal:

> exiftool -if '$xmp:Subject =~ "Drill"' -xmp:Subject-=Drill a.jpg
    1 files failed condition
> exiftool a.jpg -subject=one -subject=Drill
    1 image files updated
> exiftool -if '$xmp:Subject =~ "Drill"' -xmp:Subject-=Drill a.jpg
    1 image files updated
> exiftool a.jpg -subject
Subject                         : one


- 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 ($).

StarGeek

Your error message seems to indicate that exiftool is looking for a tag named
if '$xmp:Subject
Space and quote included. As if you're passing "-if '$xmp:Subject" to the command line.

This often indicates that the two separate arguments
-if
and
'$xmp:Subject =~ "Drill"'
are being passed to the command line as one single argument.  So you might check if the system call you are using requires each argument as a separate entry. 

Alternatively, you might try checking to make sure there's actually a space after -if and not something else like a non-break space or try different regex delimiter, as using double quotes instead of the usual slashes might be causing problems with what is passed to the command line.

"It didn't work" isn't helpful. What was the exact command used and the output.
Read FAQ #3 and use that cmd
Please use the Code button for exiftool output

Please include your OS/Exiftool version/filetype

Joanna Carter

Thanks for the hints. I've reworked it a bit so that now, in theory, I've got the following arguments...


  - 0 : "-if"
  - 1 : "'$xmp:Subject =~ Drill'"
  - 2 : "-xmp:Subject-=Drill"
  - 3 : "/Users/joannacarter/Pictures/JNA_0052.NEF"


... but, unfortunately, although it's not showing any errors, it's not doing anything to the file either :(

StarGeek

The regex binding operator =~ needs a delimiter character.  The common use would be slashes
$xmp:Subject=~/Drill/
Though just about any character can be used, as well as characters with matching open/close characters
$xmp:Subject=~!Drill!
$xmp:Subject=~(Drill)
These cases are useful when the search term has slashes that would otherwise need to be escaped (see Leaning toothpick syndrome).

In your first post, the delimiter ended up being the double quotes.
"It didn't work" isn't helpful. What was the exact command used and the output.
Read FAQ #3 and use that cmd
Please use the Code button for exiftool output

Please include your OS/Exiftool version/filetype

Joanna Carter

Once again, thank you for your ideas.

In fact, the problem was that I was including single quotes around the condition argument, as I would expect to do in macOS Terminal.

As I eventually found out, this is not necessary when invoking ExifTool from within an app.

So, now I have...


  - 0 : "-if"
  - 1 : "$xmp:Subject=~/Drill/"
  - 2 : "-xmp:Subject-=Drill"
  - 3 : "/Users/joannacarter/Pictures/JNA_0052.NEF"


In fact, now I've sorted that out, I find I can now revert to use double-quotes as a wrapping delimiter around the value to test, as well as leaving spaces between the operands and the operator...


  - 0 : "-if"
  - 1 : "$xmp:Subject =~ "Drill""
  - 2 : "-xmp:Subject-=Drill"
  - 3 : "/Users/joannacarter/Pictures/JNA_0052.NEF"


But I think I will stick with using slashes and no spaces for now.  :D

I am writing a Swift wrapper around ExifTool, to avoid having to write command lines everywhere, and now this is the syntax that I can use to conditionally delete one of the xmp:subject values:


      let arguments = [.ignoreMinorErrors, .if, .stringCondition(.xmpSubject, .contains, subject), .removeXmpSubject(subject)]


each member of the array is an Argument object, defined in an enumeration. The hope is that it should make it feel a bit less cryptic to red and write  ;)