Conditional -if to use “contains” rather than “equals”?

Started by Stephen Marsh, April 04, 2018, 09:10:39 PM

Previous topic - Next topic

Stephen Marsh

Using an -if conditional I can find images that match the following exactly:

-if '$AlphaChannelsNames eq "Transparency"'

However some other images are failing, as they contain two values:

-if '$AlphaChannelsNames eq "Transparency, Alpha 1"'

Is there an operator that I can use rather than eq (equals), such as contains? Or perhaps a regex or other method?

Or would I just have to string together two conditionals?

The issue is that there could be more than one alpha, so a contains "Transparency, Alpha" would be more flexible than an exact eq match of the string.

Hayo Baan

Yes, that's possible. Instead of eq you'd need to make use of Perl's regular expression matching operator. In your case something like this:
-if '$AlphaChannelsNames =~ /Transparency|Alpha 1/'
would select both Transparency and Alpha 1. Note, the =~ operator unleashes the full power of regular expressions.
Hayo Baan – Photography
Web: www.hayobaan.nl

Stephen Marsh

Thank you Hayo!

EDIT: I have to work through this a bit more than I first thought, however your advice has been invaluable.

exiftool -r  -if '$AlphaChannelsNames =~ /Transparency|Transparency,\s.+/' -directory=%d'Transparent Images' DIR

Phil Harvey

Quote from: Stephen Marsh on April 05, 2018, 07:58:08 AM
exiftool -r  -if '$AlphaChannelsNames =~ /Transparency|Transparency,\s.+/' -directory=%d'Transparent Images' DIR

Why not simply check for "Transparency" in the string?:

exiftool -r -if '$AlphaChannelsNames =~ /Transparency/' -directory=%d'Transparent Images' DIR

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

Stephen Marsh


Stephen Marsh

I have a very small test folder/files. When I run the following two commands separately in two passes, the process is very fast, near instant for both runs:

exiftool -r -if '$HasRealMergedData eq "No"' -directory=%d'Max Compatibility Off' DIR
exiftool -r  -if '$AlphaChannelsNames =~ /Transparency/' -directory=%d'Transparent Images' DIR


However when I attempt to combine the two conditionals, processing is very very slow. The first command takes a while but it does eventually run, while the second command never seems to complete and Terminal just sits there with the cursor flashing.

exiftool -r -if '$HasRealMergedData eq "No"' -directory=%d'Max Compatibility Off' -execute -if '$AlphaChannelsNames =~ /Transparency/' -directory=%d'Transparent Images' -execute -common_args . DIR

Is there a problem with my command (which I did cobble together from searching the forum) – or is this just to be expected?

EDIT: My input DIR is correct, however I believe that my -r may be in the incorrect position? I have a feeling that the DIR is not being correctly processed and that many more folders/files are actually being scanned...

StarGeek

The dot after -common_args will process the current dir for all 3 commands (yes, 3) in addition to DIR.  The last -execute just before -common_args adds a 3rd command, in this case it is the same as running exiftool with just the two directory names, printing out all the tags.   Finally,  move the -r so it's after -common_args so it will run with both commands.

If you suspect that exiftool is processing more files than you planned, you can add -progress to list files as they are processed.
* 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).

Stephen Marsh

Thank you StarGeek, so just to be clear... just one execute is required to combine two conditionals and move the recurse to before the DIR but after the dot and add the progress to see what is going on... Sort of like this?:

exiftool -progress -if '$HasRealMergedData eq "No"' -directory=%d'Max Compatibility Off' -execute -if '$AlphaChannelsNames =~ /Transparency/' -directory=%d'Transparent Images' -common_args . -r DIR

EDIT: Something must still be wrong - it still takes forever and I am not yet getting any progress feedback in Terminal, nor are images being moved to newly created folders when they are instantly processed when running each command separately.

Phil Harvey

You are recursively processing the current directory, and the output directory is in the current directory, so you have a good chance for infinite recursion.

If you really want the output directory inside the processed directory, the I would suggest adding a couple of ignore directories:

exiftool ... -common_args . -r DIR -i 'Max Compatibility Off' -i 'Transparent Images'

You should check, but I suspect your moved files may be buried very deeply in a directory hierarchy now. :P

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

Stephen Marsh

Thanks Phil, I used EasyFind to search for folders named so and yes, there were a few hidden away from various test runs throughout the OS. :]

Your suggestion did not appear to help, nor did adding a full absolute path to the -i command.

I think that I will have to give up and simply stick with a two pass approach.

Phil Harvey

Hi Stephen,

Stepping back...

These two commands run separately:

exiftool -r -if '$HasRealMergedData eq "No"' -directory=%d'Max Compatibility Off' DIR

exiftool -r  -if '$AlphaChannelsNames =~ /Transparency/' -directory=%d'Transparent Images' DIR


Should be identical to this combined command:

exiftool -if '$HasRealMergedData eq "No"' -directory=%d'Max Compatibility Off' -execute -if '$AlphaChannelsNames =~ /Transparency/' -directory=%d'Transparent Images' -common_args -r DIR

If you don't get the same result, then there is something wrong with ExifTool, and if so I would like to fix it.

(But again, I would suggest adding the -i options.)

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

Stephen Marsh

#11
The issue appears to be the offending . dot character in my original code. As I said, I cobbled the code together from other forum posts, so the dot may have made sense originally, but not in my specific use.

Your revised code works instantly and flawlessly Phil. So a simple case of user error and knowing just enough to be dangerous!

P.S. does the -i or -ignore use a short relative path or a full absolute path? I always believed that it had to be a full absolute path.

Phil Harvey

Hi Stephen,

From the docs:

       -i DIR (-ignore)
            Ignore specified directory name.  DIR may be either an individual
            folder name, or a full path.  If a full path is specified, it must
            match the Directory tag exactly to be ignored.  Use multiple -i
            options to ignore more than one directory name.  A special DIR
            value of "SYMLINKS" (case sensitive) may be specified to ignore
            symbolic links when the -r option is used.


- 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

An additional note, for a shorter word, it might be useful to add regex for word boundaries to avoid cases where you would get a match in a longer word.  For example, ran would also be a match for Transparency.  In such a case you would add \b to either side of the word you are trying to match, though AlphaChannelsNames is probably a bad example for ran.

'$AlphaChannelsNames =~ /\bran\b/'
* 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).

Stephen Marsh

#14
Quote from: StarGeek on April 06, 2018, 12:44:35 AM
Finally,  move the -r so it's after -common_args so it will run with both commands.

I have pretty much always added the -r directly after exiftool

So, is there any drawback to always adding the recursive command directly before the path to the DIR or FILE?

My general understanding of the order of commands is a little blurred, it does not matter on the order of arguments in the command, unless it does matter! :]

Is there a FAQ on "best practice" for using -r or the order of arguments?

StarGeek

It matters when you are using -execute.  It's more in the details of -execute and -common_args than it is an effect of -r.  When you use -execute, the command only accounts for any options up until that point.  After the -execute, it's an entirely new command and will not use any options from before the -execute.  That's why if you are using an -execute option and want to recurse through all commands, you need to put the -r after a -common_args, so it is common to all of the commands.

Here's a simple example, where the -r is right at the start of the command.  Notice how there is no recursion after the -execute.

C:\>exiftool -echo "Before Execute" -r -filename  Y:\!temp\y -execute -echo "After Execute" -filename  Y:\!temp\y
Before Execute
======== Y:/!temp/y/Test1/Img01.jpg
File Name                       : Img01.jpg
======== Y:/!temp/y/Test2/Img01.jpg
File Name                       : Img01.jpg
======== Y:/!temp/y/Test3/Img01.jpg
File Name                       : Img01.jpg
    4 directories scanned
    3 image files read
After Execute
    1 directories scanned
    0 image files read
* 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).

Stephen Marsh

Thank you StarGeek.

So even if this is the only exception to the "rule" for recursive scans, I "can't go wrong" if I just add -r command as the last argument before DIR, whether or not I am using -execute and -common_args. I'm just trying to come up with a fool proof way to use recursive scanning without having to remember the exceptions and edge cases where it does matter.

So both of these should be equivalent commands if I understand you correctly:

exiftool -if '$HasRealMergedData eq "No"' -directory=%d'Max Compatibility Off' -execute -if '$AlphaChannelsNames =~ /Transparency/' -directory=%d'Transparent Images' -common_args -r DIR

vs.

exiftool -r -if '$HasRealMergedData eq "No"' -directory=%d'Max Compatibility Off' -execute -r -if '$AlphaChannelsNames =~ /Transparency/' -directory=%d'Transparent Images' -common_args DIR

Notice the use of 2 -r commands in the second example.

Phil Harvey

Quote from: Stephen Marsh on April 10, 2018, 11:58:22 PM
I "can't go wrong" if I just add -r command as the last argument before DIR

Correct.

QuoteSo both of these should be equivalent commands if I understand you correctly:

Yes.

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

Stephen Marsh