Pattern to return a default value when a certain tag is missing

Started by metadataddicted, November 21, 2024, 03:54:15 PM

Previous topic - Next topic

metadataddicted

Hi all,
I am a total newbie, started studying this valuable tool a few days ago.

I was wondering if there is a pattern or a snippet which I can use to insert one part of a filename when the corresponding tag is missing.

Here is the case:
I would like to name my files with the following scheme:

%Y%m%d-%H%M%S_%MS#[TAKER_ID];%MAKE;%MODEL;%OP

so, for example:
20100216-120330#PG;HTC;HTC HD2 T8585;IMAG0081#HD2.JPG

This is the command line I use in a bat file in windows 11:
.\exiftool.exe -P -m -overwrite_original_in_place -wm cg "-XMP-xmpMM:PreservedFileName<${filename;$_ = undef if $self->GetValue('PreservedFileName')}"  "-filename<${datetimeoriginal;DateFmt('%%Y%%m%%d-%%H%%M%%S')}${subsectimeoriginal;$_='0'x(3-length).$_;$_='_'.$_}${offsettimeoriginal;$_=substr($_,0,3)}#PG;${make};${model};%%f.%%ue" .

Unfortunately, among the variety of devices and applications, there are some files where not all the tags are defined, such as those coming from whatsapp on android.

For these cases, I get for example:
#PG;;;IMG-20241118-WA0003#GalaxyS22U.JPG

I was wondering if there is some trick I can use to fill a default value with the missing tags, such as maker and model. I will figure out how to deal with the missing DateTimeOriginal in a different way.

It would be useful something like
-'filename<Helper(TAG;DEFAULT_VALUE_IF_TAG_IS_UNDEF)'

I tried to play with some of the patterns I found around on the forum and on the documentation but I can't figure out anything similar.

I guess the if construct is not an option since I would like to cover several tags in the filename with a unique line.

In your experience is there some way to deal with this issue?

Thank you in advance.




StarGeek

There are a variety of things you can do. Adding the -m (-ignoreMinorErrors) option will cause a nonexistent tag to exist with a 0-length value "". The -f (-ForcePrint) option will cause nonexistent tags to be set to a minus sign - and that can be changed by using the -API MissingTagValue option.

You could also make multiple assignments to Filename to cover every option. See Note #1 under the -TAG[+-^]=[VALUE] option. Though that would get rather long if used on the command line.

Rather than a long command line, you could save all the options to an ARGS file and use the -@ (Argfile) option

Example, save this as Rename.args
# both make and model don't exist
-filename<${datetimeoriginal;DateFmt('%%Y%%m%%d-%%H%%M%%S')}${subsectimeoriginal;$_='0'x(3-length).$_;$_='_'.$_}${offsettimeoriginal;$_=substr($_,0,3)}#PG;Unknown Make;Unknown Model;%%f.%%ue
# make is missing
-filename<${datetimeoriginal;DateFmt('%%Y%%m%%d-%%H%%M%%S')}${subsectimeoriginal;$_='0'x(3-length).$_;$_='_'.$_}${offsettimeoriginal;$_=substr($_,0,3)}#PG;Unknown Make;${model};%%f.%%ue
# model is missing
-filename<${datetimeoriginal;DateFmt('%%Y%%m%%d-%%H%%M%%S')}${subsectimeoriginal;$_='0'x(3-length).$_;$_='_'.$_}${offsettimeoriginal;$_=substr($_,0,3)}#PG;${make};Unknown Model;%%f.%%ue
# Make and Model exist
-filename<${datetimeoriginal;DateFmt('%%Y%%m%%d-%%H%%M%%S')}${subsectimeoriginal;$_='0'x(3-length).$_;$_='_'.$_}${offsettimeoriginal;$_=substr($_,0,3)}#PG;${make};${model};%%f.%%ue

You could then use this command. I removed the complex check for writing PreservedFileName because it isn't need due to the -wm cg (-writeMode cg) option. -wm cg prevents writing to existing tags. I also removed the -m because if you were to use this command, including -m means that Make/Model always exists and the first three options would never get used
exiftool.exe -P -overwrite_original_in_place -wm cg "-XMP-xmpMM:PreservedFileName<filename" -@ /path/to/Rename.args

One thing to point out. You are setting SubSecTimeOriginal incorrectly. You are prepending 0s when you should be appending 0s. For example, given three files taken in the same second, one with a subsecond of 7/100 (.07), 1/2 (50/100) (.5), and 42/100 (.42). The correct order should be 7/100, 42/100, 50/100. But your command ends up with _007, _005, _042

C:\>exiftool -G1 -a -s -SubSecDateTimeOriginal y:\!temp\Test3.jpg y:\!temp\Test4.jpg y:\!temp\Test5.jpg 
======== y:/!temp/Test3.jpg
[Composite]     SubSecDateTimeOriginal          : 2024:11:22 12:00:00.07
======== y:/!temp/Test4.jpg
[Composite]     SubSecDateTimeOriginal          : 2024:11:22 12:00:00.5
======== y:/!temp/Test5.jpg
[Composite]     SubSecDateTimeOriginal          : 2024:11:22 12:00:00.42
    3 image files read

C:\>exiftool -G1 -a -s -p "${subsectimeoriginal;$_='0'x(3-length).$_;$_='_'.$_}" y:\!temp\Test3.jpg  y:\!temp\Test4.jpg y:\!temp\Test5.jpg
_007
_005
_042
    3 image files read

C:\>exiftool -G1 -a -s -p "${subsectimeoriginal;$_='_'.$_.'0'x(3-length)}" y:\!temp\Test3.jpg  y:\!temp\Test4.jpg y:\!temp\Test5.jpg
_070
_500
_420
    3 image files read
"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

StarGeek

Here's a better replacement for the subseconds. Note that this is using SubSecDateTimeOriginal instead of SubSecTimeOriginal
${SubSecDateTimeOriginal;DateFmt('%-3f')} See Note #1 under Common Date Format Codes.

C:\>exiftool -G1 -a -s -p "${SubSecDateTimeOriginal;DateFmt('%-3f')}" y:\!temp\Test3.jpg  y:\!temp\Test4.jpg y:\!temp\Test5.jpg
070
500
420
    3 image files read

Since you said you are using a BAT file, the percent sign would have to be doubled.
"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

metadataddicted

Hi StarGeek,
I apologize for the late reply but it took me a while to understand your enlighting suggestions.

In the end I came up with a Windows 11 bat file, which includes a batch of calls similar to this one, for example, each one covering a different case.

set GlobalParams=-charset filename=utf8 -P -overwrite_original_in_place -wm cg

ECHO CASE 06
:: CASE 06a "20181130-152544_000;PG;Unknown brand;Unknown model;LGTH4667.JPG" [FileName]
:: CASE 06b "20181130-152544_000;PG;Unknown brand;Unknown model;LGTH4667.JPG" [SubSecDateTimeOriginal;FileName]
%ExifTool% %GlobalParams% ^
    "-FileName<${Filename;s/^(\d{8})-(\d{6})_(\d{3});([^;]*);([^;]*);([^;]*);([^\[]*)\.(.*)/06a-$1-$2.###+####;$4;$5;$6;\[$7.%%e\]/}%Dbg_FullName%.%%ue" ^
    "-FileName<${SubSecDateTimeOriginal;DateFmt('06b-%%Y%%m%%d-%%H%%M%%S.%%-3f%%z')};${FileName;s/^(\d{8})-(\d{6})_(\d{3});([^;]*);([^;]*);([^;]*);([^\[]*)\.(.*)/$4;$5;\[$6.$7\]/}%Dbg_FullName%.%%ue" ^
    "-XMP-xmpMM:PreservedFileName<${FileName;s/^(\d{8})-(\d{6})_(\d{3});([^;]*);([^;]*);([^;]*);([^\[]*)\.(.*)/$7.%%e/;$_ = undef if $self->GetValue('PreservedFileName')}" ^
    "-XMP-xmpMM:PreservedFileName<${FileName;s/^(\d{8})-(\d{6})_(\d{3});([^;]*);([^;]*);([^;]*);([^\[]*)\.(.*)/$7.%%e/;$_ = undef if $self->GetValue('PreservedFileName')}" ^
    -if "$Filename=~/^\d{8}-\d{6}_\d{3};[^;]*;[^;]*;[^;]*;[^\[]*\.(?i:JPG)/" ^
    .\test\

It is not as straightforward as I would like but it works to manage the diversity of files I have. Maybe you can see further space to improve it.

I still have one question, when it is not possible to extract the timezone, I would like to use as fall back value: '±####' but I do not understand how to place the '±' character (\u001B) in the filename. I tried several escape options but none seems to work.

Do you have a suggestion on this?
Thanks




StarGeek

Quote from: metadataddicted on December 13, 2024, 12:32:37 PMI still have one question, when it is not possible to extract the timezone, I would like to use as fall back value: '±####' but I do not understand how to place the '±' character (\u001B) in the filename. I tried several escape options but none seems to work.

Does it not work when you simply use ±?  Under CMD, it should not need escaping.
"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