News:

2023-03-15 Major improvements to the new Geolocation feature

Main Menu

if statement syntax using variables

Started by ulrichk7, February 08, 2018, 12:41:28 PM

Previous topic - Next topic

ulrichk7

Hi,
right after registring my first words are a big thank you for this brilliant tool!!
My question is supposed to be very simple, but I could not find anything in search , man-page, FAQ etc. (maybe it's too simple and I just lost my way....).

Background is that I want to see the picture-files in a directory that come with a certain lens model.
No problem using (in Linux):
exiftool -q -s3 -if '$LensModel eq "A Series Lens"' -FileName .

Now I need to use this in a small script (bash), that first  collects all LensModels of all picture files in an array and runs a loop so that the part "A Series Lens" will be replaced by a variable called $objektive.
Non of the following syntax works (I know that the spaces in "A Series Lens" causes the problem, but I will always have a lens that has spaces in the name):

exiftool -s3 -if '$LensModel eq "$objektiv"' -FileName .
exiftool -s3 -if '$LensModel eq """$objektiv"""' -FileName .
exiftool -s3 -if '$LensModel eq \"$objektiv\"' -FileName .
exiftool -s3 -if '$LensModel' eq "$objektiv" -FileName .


Etc (I tries many more including ${objektiv} $(objektiv)..... (IFS is set to \n also, see script below)
You see from the examples that I am not an experienced perl user, hope it's an easy question for you.

So, what is the right syntax?

In case the whole script is of interest:

#!/bin/bash
objektivliste=`exiftool -q -s3 -LensModel .`

#sorting and removing doubles
IFS=$'\n'
objektivliste=($(sort -u <<<"${objektivliste[*]}"))

for objektiv in "${objektivliste[@]}"; do
   echo "Lens $objektiv is used in:"

#### this is the problem:
   exiftool -if -q -s3 '$LensModel' eq "$objektiv" -FileName .
####
done
unset IFS








Phil Harvey

To go sideways a bit...

You could do something cool like this:

exiftool '-hardlink<DSTDIR/${lensmodel;}/%f%-c.%e' -r SRCDIR

This will create a set of directories in DSTDIR named by the lens model with hardlinks to the original files.

But to answer your question, the quoting is the problem, but you could do it like this:

exiftool -s3 -if '$lensModel eq '"'$objectiv'" -FileName .

Here I change to double quotes so $objectiv will be expanded by the shell, and put single quotes inside this for the Perl string.

- 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

I was waiting because I wanted to se an actual bash answer, but this is the solution I came up with
exiftool -userparam "MyModel=$objectiv" -if '$lensModel eq $MyModel'
* 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).

ulrichk7

Perfect! thank you, both works!

@Phil: thank you for the sideway, but the final idea is not to create subfolders. The idea behind is that I am using some lenses from the "good old" analog days - they are noted as "A Series Lens", then I have one Sigma Lens, that unfortunately is only named "Sigma" (without the model indication) and lenses that are fully recognized.

My script should
1. list the the lens that were used according to the LensModel tag (after processing a shooting day, which means all jpg's on my "raw-processing folder") - this works
2. read from user-input, which "LensModel" tag should be replaced - that's easy
3. present a list of my lenses and let me select the one used - also easy
4. write the selected (from pt. 3) to the LensModel tag of the files that have the LensModel Tag I selected in 2 - this is what I needed the if statement for, for testing it was simply displaying the file name, later it will become "write the LensModel tag".

Sounds complex, but the example is: Coming back from a photo day where I used my Pentax smc 1/1.4 50mm and my Sigma DC 18-50mm 1:2.8 EX.

Step one gives me:
"A Series Type" (as the old MF Pentax smc 1/1.4 50mm does not talk to the camera body) and
"Sigma" (as the model is not recognized).

In step 2 I select the first entry "A Series Type"
Step 3 shows me all my lenses, from that list I select "Pentax smc 1/1.4 50mm"
Step 4 replaces "A Series Lens" with "Pentax smc 1/1.4 50mm".

Repeating that for Sigma and that's it.
That's the max of automatisation that's possibel, because in another day "A Series Type" could also mean "Tokina ATX ....".

Just to mention: Before all this there is an eaven simpler script that's writing the LensID from the maker note taken from the cameras DNG file to the LensModel exif tag of the jpg file with the same base name. This part is in use for quite some years now.

Again: great tool!

chuck lee

#4
Dear all,

Exiftool is the best tool for me to handle my photos.  Thank you for this thread and other similar ones.  Now, I can simplify my script and update it easily. 
My work is simple, I have a lot of scanned old photos with file names not very consistent:
  19700325_where_who_event 001.jpg
  198008xx_event_002.JPG
  1965XXXX_event-04.jpg
  19800615_10xxxx event 010.jpg
  ....
I want to write the datetimeoriginal tag according to the file name and archive them into YYYYmm/dd/img_file.  Unlike the photoes taken from digital camera, datetimeoriginal is set automatically.  The second step is I want to generate a corresponding heic format file that keeps the datetimeoriginal and orientation tags.  Thus, the statement of if conditions and operations becomes complicated and a long string.  Argfile is a good choice, however, I have to open and update several argfiles at the same time feels annoying.

Then, from the thread, I came up with if I can set the arguments as variables and make a pseudo argfile to handle the process will save me the time to debug.


init_var()
{
  # func_counter
  # sub_title "" "$func_num" "$FUNCNAME() --> `basename ${BASH_SOURCE[0]}` --> `basename $0`"

  ifs=''   # exiftool if argumant

  if_cond=''  # eixftool if conditions in string 

  op=''  # exiftool operation

  dest_dir=''  # exiftool destination dir

  # exiftool options
  option='-q -fast2 -overwrite_original -fileorder4 directory -fileorder4 filename'

  [[ "$recursive" == "r" ]] && option+=" -r"   # if recursive
 
  file_type="-ext heic -ext jpg"
 
  ignore_dir="-i 0_lt_50k -i 0_manual -i jpg -i heic -i dto_y -i dto_n"

  src_dir=' . '  # exiftool source dir
}

exif_process()
{
exif_arg="${ifs} ${if_cond} ${dest_dir} ${op} ${option} ${progress} ${file_type} ${src_dir} ${ignore_dir} ${misc}"

sed_arg='s/\s+/ /g;s/ not / not/g;s/ (and|or|eq|ne|lt|gt|le|lt) /~~\1~~/g;s/\s/\n/g;s/~~/ /g'
# s/\s+/ /g  --- subsitute multiple spaces with one space
# s/ not / not/g  --- remove the space between 'not' and 'condition', use 'not' instead of '!'
# s/ (and|or|eq|ne|lt|gt|le|lt) /~~\1~~/g  --- subsitute space with '~~' before and after these operators
# s/\s/\n/g  --- substitute remaining space with newline
# s/~~/ /g'  --- substitute '~~' back to space
# This sed_arg will make the string fit into exiftool argfile format.

{ err=$( { { echo "${exif_arg}" | sed -r "$sed_arg" | exiftool -@ - ; } 1>&$tmp ; } 2>&1); } {tmp}>&1; exec {tmp}>&-
# pipe "${exif_arg}" variable to sed and output as the argfile for exiftool, also the err variable from the stderr will be checked next

chk_err  # function to check error
}


# For example:

init_var   # initialize variables
ifs='-if2'
file_min_size=50000
lt_min_size='$filesize#<='"$file_min_size"
# all the variable value should not have any space and variable should double quoted
dto_ymd='${datetimeoriginal;s/\D//g;$_=substr($_,0,8)}'
dto_hms='${datetimeoriginal;s/\D//g;$_=substr($_,8,6)}'
fn_ymd='${filename;$_=substr($_,0,8)}'
# .
# .
# .
dto_ymd_fn="$dto_ymd"'=~'"$fn_ymd_x_1"
# .
# .
dto2fn_ymd='-filename<'"$dto_ymd"'_${filename;s/^\d{8}_//;s/IM[^_]_//i;s/\.[^.]*$//}.%le'
  # dto YYYYmmdd_ replace original prefix of the filename
# .
# .
if_cond="not $fn_hms_field and not $dto_hms_eq_0"
op="$dto2fn_hms_add"
# I only have to change the argument variable I want :)

exif_process
# .
# .



You make my life easier, thanks.
chuck