Renaming files along with their xmp pair

Started by Paulera, September 03, 2024, 05:02:41 PM

Previous topic - Next topic

Paulera

Hi.

I've been using this awesome tool through a Windows Batch file to (hopefully) rename all my over 60k personal pictures.
I have them separated in folders by year\month, and am working from the newest going back.

The batch file I use renames the files based on geolocation, date and time, like so:

exiftool -m -api largefilesupport=1 -api geolocation "-filename<${FileModifyDate} ${geolocationregion;s/S.*Paulo/SP/;s/Rio de Janeiro/RJ/;},${GeolocationCity;s/Santo Andr../Santo Andre/;s/Consola.*/Consolacao/;s/Guaruj.*/Guaruja/;s/Jaragu.*/Jaragua/;s/Para..so/Paraiso/;s/S..o Jo..o/Sao Joao/;s/Esp..rito/Espirito/;}${Title;}.%%e" -d "%%Y'%%m'%%d %%a %%H'%%M'%%S%%%%-c" %1
REM The regexp substitutions is to get rid of diacritics
exiftool -m -api largefilesupport=1 "-filename<${filename;s/ ,//}" %1
REM The command above is to get rid of a " ," in the filename in the case no geolocation is returned.

Resulting in something like this:
2024'01'30 Tue 17'12'28 SP,Guaruja.HEIC
2024'08'01 Thu 10'40'16 SP,Parque da Agua Branca.HEIC

Couple of months ago I bought a windows software to manage these pictures, basically adding faces positions and names to the metadata.
Since I ran that software through all the pictures, even those I still had not renamed, I would like to rename them while retaining this new metadata.
Unfortunately, that software adds such metadata to a sidecar xmp file and that xmp file includes the extension of the paired file, for example:

IMG_7535.HEIC
IMG_7535.HEIC.xmp
P5060205.JPG
P5060205.JPG.xmp

I searched the forum and found a suggestion that almost solves this exact problem, but the xmp file must not have the original file extension in its name or it won't work.
I couldn't figure out how to make it work for my case.

The solution presented was this:

exiftool -m -api largefilesupport=1 -api geolocation -tagsfromfile "%%d%%f.HEIC" "-filename<${FileModifyDate} ${geolocationregion;s/S.*Paulo/SP/;s/Rio de Janeiro/RJ/;},${GeolocationCity;s/Santo Andr../Santo Andre/;s/Consola.*/Consolacao/;s/Guaruj.*/Guaruja/;s/Jaragu.*/Jaragua/;s/Para..so/Paraiso/;s/S..o Jo..o/Sao Joao/;s/Esp..rito/Espirito/;}${Title;}.%%e" -d "%%Y'%%m'%%d %%a %%H'%%M'%%S%%%%-c" -ext HEIC -ext xmp -fileOrder -fileextension -o %1\renamed %1

This works perfectly when the sidecar pair is named like this:
IMG_7535.HEIC
IMG_7535.xmp

But doesn't work if named like this:
IMG_7535.HEIC
IMG_7535.HEIC.xmp

How may adapt that solution for my case where the xmp file has its pair extension in its name?

Any pointer appreciated, thanks in advance!

Desired results:
2024'01'30 Tue 17'12'28 SP,Guaruja.HEIC
2024'01'30 Tue 17'12'28 SP,Guaruja.HEIC.xmp
2024'08'01 Thu 10'40'16 SP,Parque da Agua Branca.HEIC
2024'08'01 Thu 10'40'16 SP,Parque da Agua Branca.HEIC.xmp

Best regards,
Paulo

StarGeek

What appears to be happening is in the case of IMG_7535.HEIC.xmp, then %f is going to have the value of IMG_7535.HEIC, as %f is the base filename without the xmp extension. The result format for the -TagsFromFile option ends up as\
IMG_7535.HEIC.HEIC.

What needs to be done in this case is to remove the .HEIC from the %f. This can be done using the % variables advanced features (see the -w (-TextOut) option).

To remove the last 5 characters (dot included), you would use %-.5f

This would need to be changed to 4 in the case of P5060205.JPG.xmp.

You could either run two (or more with multiple different extensions) separate commands, or you can use the fact that you can use multiple -TagsFromFile in the same command, depending on the fact that if one file doesn't exist, then exiftool can't copy tags from it. This will throw an error or warning, I'm not sure which.

But this does make a big and messy looking command
exiftool -m -api largefilesupport=1 -api geolocation -tagsfromfile "%%d%%f.HEIC" "-filename<${FileModifyDate} ${geolocationregion;s/S.*Paulo/SP/;s/Rio de Janeiro/RJ/;},${GeolocationCity;s/Santo Andr../Santo Andre/;s/Consola.*/Consolacao/;s/Guaruj.*/Guaruja/;s/Jaragu.*/Jaragua/;s/Para..so/Paraiso/;s/S..o Jo..o/Sao Joao/;s/Esp..rito/Espirito/;}${Title;}.%%e" -tagsfromfile "%%d%%f.jpg" "-filename<${FileModifyDate} ${geolocationregion;s/S.*Paulo/SP/;s/Rio de Janeiro/RJ/;},${GeolocationCity;s/Santo Andr../Santo Andre/;s/Consola.*/Consolacao/;s/Guaruj.*/Guaruja/;s/Jaragu.*/Jaragua/;s/Para..so/Paraiso/;s/S..o Jo..o/Sao Joao/;s/Esp..rito/Espirito/;}${Title;}.%%e" -d "%%Y'%%m'%%d %%a %%H'%%M'%%S%%%%-c" -ext jpg -ext HEIC -ext xmp -fileOrder -fileextension -o %1\renamed %1

* 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).

Paulera

Ah I see it now, I wasn't quite getting that solution before!

Thank you so much for the thorough explanation and for the suggestion of how to make it all work with a single command.

Here is my resulting batch file with variables to try and make the resulting command look less messy and easier to add regex substitutions in the future.:
@echo off
set region.regex=s/S.*Paulo/SP/;s/Rio de Janeiro/RJ/;
set city.regex=s/Santo Andr../Santo Andre/
set city.regex=%city.regex%;s/Consola.*/Consolacao/
set city.regex=%city.regex%;s/Guaruj.*/Guaruja/
set city.regex=%city.regex%;s/Jaragu.*/Jaragua/
set city.regex=%city.regex%;s/Para..so/Paraiso/
set city.regex=%city.regex%;s/S..o Jo..o/Sao Joao/
set city.regex=%city.regex%;s/Esp..rito/Espirito/
set city.regex=%city.regex%;
set new.name=${FileModifyDate} ${geolocationregion;%region.regex%},${GeolocationCity;%city.regex%}${Title;}

exiftool -m -api largefilesupport=1 -api geolocation ^
-tagsfromfile "%%d%%f.%%e" "-filename<%new.name%.%%e" ^
-tagsfromfile "%%d%%-.5f.HEIC" "-filename<%new.name%.HEIC.%%e" ^
-tagsfromfile "%%d%%-.4f.jpg" "-filename<%new.name%.JPG.%%e" ^
-d "%%Y'%%m'%%d %%a %%H'%%M'%%S%%%%-c" ^
-fileorder -filename %1

exiftool -m -api largefilesupport=1 "-filename<${filename;s/ ,//}" %1


Quote from: StarGeek on September 03, 2024, 05:49:14 PMThis will throw an error or warning, I'm not sure which.
It throws "Warning: Error opening file"

StarGeek

Quote from: Paulera on September 03, 2024, 11:26:59 PM
Quote from: StarGeek on September 03, 2024, 05:49:14 PMThis will throw an error or warning, I'm not sure which.
It throws "Warning: Error opening file"

So, both?  ;)

Ok, it's just a warning. If you want, you can suppress it by adding this to your command
-api NoWarning="Error opening file"
* 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).

Paulera

;D

Quote from: StarGeek on September 03, 2024, 11:39:18 PM-api NoWarning="Error opening file"
Ah yes, I have been trying to figure that one out before to no avail, thank you!

I hope you don't mind me asking since my problem was solved already way better than I was hoping for, but any suggestions on how to make that last substitution in one go?

For instance, would it be possible to apply a regex substitution to this whole portion?

${FileModifyDate} ${geolocationregion;%region.regex%},${GeolocationCity;%city.regex%}${Title;}

I mean, after everything gets resolved but before sending it to the filename tag?

Or would it be possible to use some Perl inside the tag itself to conditionally add a " " before and a "," after the tagvalue if geolocationregion not blank, for instance?

For context, if an image doesn't have GPS metadata, this is the resulting filename:
2018'05'11 Fri 11'38'22 ,.JPG

StarGeek

Quote from: Paulera on September 04, 2024, 03:44:56 PM
Quote from: StarGeek on September 03, 2024, 11:39:18 PM-api NoWarning="Error opening file"
Ah yes, I have been trying to figure that one out before to no avail, thank you!

The part that stumped for a bit was that you don't include the "Warning: " text. Just the actual text of the warning itself. And you can use Regex with this.

QuoteFor instance, would it be possible to apply a regex substitution to this whole portion?

${FileModifyDate} ${geolocationregion;%region.regex%},${GeolocationCity;%city.regex%}${Title;}

I mean, after everything gets resolved but before sending it to the filename tag?

Not really. But you can simplify it by creating a Helper function similar to the built in ones. You need to have an .exiftool_config file though (see the example.config file for instructions).

I am ignoring the -api Filter option for this as it is global and will affect all tags, which is probably not what you would want.

In this case it would be really simple. You would place this by itself in the .exiftool_config file. Some part which isn't already indented, so it can't be between any section that starts with %Image::ExifTool:: and the matching close parenthesis ).
sub CitySubs {
    s/Santo Andr../Santo Andre/;
    s/Consola.*/Consolacao/;
    s/Guaruj.*/Guaruja/;
    s/Jaragu.*/Jaragua/;
    s/Para..so/Paraiso/;
    s/S..o Jo..o/Sao Joao/;
    s/Esp..rito/Espirito/;
}

I ususally place helper functions near the top. In the .exiftool_config file, I would do this, placing it right above the Shortcut Tags section

#------------------------------------------------------------------------------

sub CitySubs {
    s/Santo Andr../Santo Andre/;
    s/Consola.*/Consolacao/;
    s/Guaruj.*/Guaruja/;
    s/Jaragu.*/Jaragua/;
    s/Para..so/Paraiso/;
    s/S..o Jo..o/Sao Joao/;
    s/Esp..rito/Espirito/;
}

# Shortcut tags are used when extracting information to simplify
# commonly used commands.  They can be used to represent groups
# of tags, or to provide an alias for a tag name.
%Image::ExifTool::UserDefined::Shortcuts = (
    MyShortcut => ['exif:createdate','exposuretime','aperture'],
    MyAlias => 'FocalLengthIn35mmFormat',
);

Or, if you didn't want a full config file, you could the sub by itself in an .exiftool_config.

The resulting tag would be
${GeolocationCity;CitySubs;}

I didn't know if you wanted to insert the region regex here or make a separate function.

QuoteOr would it be possible to use some Perl inside the tag itself to conditionally add a " " before and a "," after the tagvalue if geolocationregion not blank, for instance?

Assuming you made a RegionSub helper function, I think this would work.
${geolocationregion;$_=($_):' '.$_.','?'';RegionSub;}

This part
$_=($_):' '.$_.','?'';
probably could be moved to the RegionSub, first line after the sub line. It assumes the value of geolocationregion is a zero length string ''. I haven't used the geolocate function, so I don't know what is returned it that part fails.

This is all off the top of my head, so I haven't tested it. But I think it should work.
* 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).

Paulera

Quote from: StarGeek on September 04, 2024, 06:45:57 PMyou can simplify it by creating a Helper function similar to the built in ones. You need to have an .exiftool_config file
Neat! I already had a config file for personal geolocation places, creating the subs worked great, and way easier on the eyes than the batch variables!

Quote from: StarGeek on September 04, 2024, 06:45:57 PMAssuming you made a RegionSub helper function, I think this would work.
${geolocationregion;$_=($_):' '.$_.','?'';RegionSub;}
This is beautiful! I just had to swap the : with the ? and it worked perfectly!
You are awesome!

Here is the resulting batch file:
@echo off
set new.name=${FileModifyDate}${geolocationregion;$_=($_)?' '.$_.',':'';RegionSubs;}${GeolocationCity;CitySubs;}${Title;}

exiftool -m -api largefilesupport=1 -api geolocation -api NoWarning="Error opening file" ^
-tagsfromfile "%%d%%f.%%e" "-filename<%new.name%.%%e" ^
-tagsfromfile "%%d%%-.5f.HEIC" "-filename<%new.name%.HEIC.%%e" ^
-tagsfromfile "%%d%%-.4f.jpg" "-filename<%new.name%.JPG.%%e" ^
-d "%%Y'%%m'%%d %%a %%H'%%M'%%S%%%%-c" ^
-fileorder -filename %1

StarGeek

Quote from: Paulera on September 04, 2024, 10:29:51 PMI just had to swap the : with the ? and it worked perfectly!

Ack! What was wrong with my brain! That's a silly mistake.

Glad it's working out for you.
* 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).