ExifTool Forum

ExifTool => The "exiftool" Application => Topic started by: sheepthief on December 02, 2023, 07:13:56 AM

Title: Splitting a multi-value string for conditional inclusion in output
Post by: sheepthief on December 02, 2023, 07:13:56 AM
So close, and yet so far, and I'm going around in circles searching for a solution...

I'm looking to rename a large directory of files, preserving the first two characters of the filename, then using the unix epoch time, then a drivemode value (Olympus) to append a sequence number if the image was part of a sequence.

So far I've got this
exiftool -q -q -ext jpg -recurse . -preserve -n -p "${filename;$_=substr($_,0,2)}${datetimeoriginal;DateFmt('%s%f')}-${drivemode}.${filetypeextension}"

Which returns something like this (the first image is part of a sequence, the second is not)
EA1700483034-5 6 1 0 4 35.JPG
OS1700522905-0 0 0 0 0 1.JPG

I'd like to append the second number of the drivemode string to the filename, if and only if it is non-zero. But I can't figure out how to separate out just the second number for testing and for possible inclusion in the filename.

That's the first problem. The second problem is that some of the images are from a mobile phone which lacks the drivemode variable, and those are entirely missing from the output.

Additional: if possible I'd like to force the sequence number to three digits, with leading zeros.
Title: Re: Splitting a multi-value string for conditional inclusion in output
Post by: StarGeek on December 02, 2023, 10:07:24 AM
Quote from: sheepthief on December 02, 2023, 07:13:56 AMI'm looking to rename a large directory of files
...
The second problem is that some of the images are from a mobile phone which lacks the drivemode variable, and those are entirely missing from the output.

Will you be renaming with exiftool or are you using exiftool to produce a list which will do the renaming in another program. I ask because of your use of the -p (-printFormat) option (https://exiftool.org/exiftool_pod.html#p-FMTFILE-or-STR--printFormat) which would make things more difficult if it is for use outside of exiftool.

If it is within exiftool, you can use assignment precedence (see note #1 under the -TAG[+-^]=[VALUE] option (https://exiftool.org/exiftool_pod.html#TAG---VALUE)) to deal with the existance of DriveMode or not.
exiftool "-Filename<${filename;$_=substr($_,0,2)}${datetimeoriginal;DateFmt('%s%f')}.%e" "-Filename<${filename;$_=substr($_,0,2)}${datetimeoriginal;DateFmt('%s%f')}-${drivemode}.%e" /path/to/files/

In this command, if DriveMode exists, it will use the latter rename, otherwise it will fallback to the first rename.  I did change FileTypeExtension to %e as you would only want to use FileTypeExtension if the file was missing or had an incorrect extension.

Just to verify, since I am not familiar with the Olympus DriveMode tag, it is the six numbers? "5 6 1 0 4 35" and "0 0 0 0 0 1"?

For DriveMode, try using this
${DriveMode;s/.*(\d+) \d+$/$1/;$_=($_)?sprintf('%03d', $_ ):''}

Breakdown
s/.*(\d+) \d+$/$1/ is a regex substitution, removing all of the characters except for the second to last digit group.
$_=($_)?sprintf('%03d', $_ ):'' is a Perl conditional operator.  If the new value of the tag is not 0, then it will pad it with leading 0s to 3 digits sprintf('%03d', $_ ) otherwise it will be blank.



Title: Re: Splitting a multi-value string for conditional inclusion in output
Post by: sheepthief on December 02, 2023, 11:45:21 AM
Superb! Thanks!

It's decades since I did any proper programming, and never Perl, so while I thought it must be possible it was a question of getting the right incantation.

I take on board what you say about -p not being suitable for use outside of exiftool, so I'll look at that later. And yes, "5 6 1 0 4 35" is an example of the drivemode variable, though it's the second number that's the sequence number (or 0 if not part of a sequence). So, the following seems to work...

exiftool -q -q -ext jpg -ext orf -ext ori -recurse . -preserve -n -p "rename ${filepath} ${filename;$_=substr($_,0,2)}${datetimeoriginal;DateFmt('%s%f')}${DriveMode;s/(\d+) /$2/;s/(\d+).*/$1/;$_=($_)?sprintf('-%03d',$_):''}.${filetypeextension}"

Example output being...

rename C:/Users/mel/Desktop/20231120/EM1mkIII/1223-EA/EA231120122354003.jpg EA1700483034-004.JPG
rename C:/Users/mel/Desktop/20231120/EM1mkIII/1223-EA/EA231120122354003.ORF EA1700483034-004.ORF
rename C:/Users/mel/Desktop/20231120/EM1mkIII/1223-EA/EA231120122354004.jpg EA1700483034-005.JPG
rename C:/Users/mel/Desktop/20231120/EM1mkIII/1223-EA/EA231120122354004.ORF EA1700483034-005.ORF
rename C:/Users/mel/Desktop/20231120/EM1mkIII/1223-EA/EA231120122354005.jpg EA1700483034-006.JPG
rename C:/Users/mel/Desktop/20231120/EM1mkIII/1223-EA/EA231120122354005.ORF EA1700483034-006.ORF
rename C:/Users/mel/Desktop/20231120/OM1/2328-OS/OS231120232825001.jpg OS1700522905.JPG
rename C:/Users/mel/Desktop/20231120/OM1/2328-OS/OS231120232825001.ORF OS1700522905.ORF
rename C:/Users/mel/Desktop/20231120/OM1/2328-OS/OS231120232858001.jpg OS1700522938.JPG
rename C:/Users/mel/Desktop/20231120/OM1/2328-OS/OS231120232858001.ORF OS1700522938.ORF

I'll take a full backup then test on some example images, then look into doing the renaming from within exiftool, and including phone images that have no drivemode variable.

Oh, %e didn't seem to work for the extension (or %%e, given that I'm on windows), but ${filetypeextension} appears to match what the images are.

Thanks again!
Title: Re: Splitting a multi-value string for conditional inclusion in output
Post by: StarGeek on December 02, 2023, 12:26:34 PM
Quote from: sheepthief on December 02, 2023, 11:45:21 AMI take on board what you say about -p not being suitable for use outside of exiftool

I don't mean it's not suitable, it's just that it would be more difficult to deal with if the tag doesn't exist.

Under normal circumstances, if a tag doesn't exist, then that part of the command will fail.  You can use a couple options to change a tag so it exists, but that will affect all tags that don't exist.

First is the -m (-ignoreMinorErrors) option (https://exiftool.org/exiftool_pod.html#m--ignoreMinorErrors).  From the docs
QuoteNote that this causes missing values in -tagsFromFile, -p and -if strings to be set to an empty string rather than an undefined value.

The second is the -f (-ForcePrint) option (https://exiftool.org/exiftool_pod.html#f--forcePrint). Here, missing tags will have a value of - but that can be changed with the -api MissingTagValue option (https://exiftool.org/ExifTool.html#MissingTagValue) like this -api "MissingTagValue^="

As a straight exiftool command, this should work
exiftool -q -q -ext jpg -ext orf -ext ori -recurse . -preserve -n "-Filename<${filename;$_=substr($_,0,2)}${datetimeoriginal;DateFmt('%s%f')}.${filetypeextension}" "-Filename<${filename;$_=substr($_,0,2)}${datetimeoriginal;DateFmt('%s%f')}${DriveMode;s/(\d+) /$2/;s/(\d+).*/$1/;$_=($_)?sprintf('-%03d',$_):''}.${filetypeextension}"

But there's no problem is using exiftool to create a bat file to run in the way you are doing.  The only thing you don't want to do is put exiftool in a loop, as its startup time is the biggest performance hit and looping it will greatly extend processing time (see Common Mistake #3 (https://exiftool.org/mistakes.html#M3)).
Title: Re: Splitting a multi-value string for conditional inclusion in output
Post by: sheepthief on December 02, 2023, 10:23:56 PM
The -m option works perfectly in my case, so thanks for that, that's great.

Aye, I've noticed the startup time, as some of my scripts have to process images individually - I keep meaning to look into the options that keep exiftool resident in memory, but it's no big deal - in my particular case time isn't an issue and I can go make a coffee or leave it running overnight.

EDIT: aha! Looks like the use of %-c could fix both of the potential issues mentioned below...

Oh, you were spot on about the use of ${filetypeextension}. It isn't a problem for me but a note of caution for any other Olympus users who might read this: if you shoot in the special hi-res mode that saves the combined image as ORF and the first component image as ORI, it will rename the ORI file to ORF. In my case there's no naming conflict because they're already sorted into different folders, and I prefer the ORF extension anyway. But, there's no sequence number, so there's potentially a naming conflict if they're in the same folder.

The only thing I now perhaps need to consider is a case where two or more shots are taken in a non-sequential mode but within 1 second - in that case there would be a file naming conflict due to using the unix epoch time with a one second resolution. It's unlikely that I'll have any such cases - I'll deal with that if it ever happens.