Combine conditional & unconditional update into one command

Started by mbuzina, July 11, 2021, 01:35:25 PM

Previous topic - Next topic

mbuzina

I have a large csv file exported from my DAM, which contains writeable information (writing works fine) for several 10s of thousands of images. I have tested this with a subset of about 5000 and, kudos, it works great (I have a seperate file list with the names which I use the @ function to redirect input). I have one issue, though.

For all files I have an update on Subject & Keywords as well as Location data and for some I have region info. All of this is written to the files. But I also have a DateTimeOriginal which I would like to write ONLY if there are no useable dates in the file (AllDates is empty). I can do this with an -if "not $alldates" and again it works, but this way I have to do two passes in writing, since the if statement effects ALL updates.

Is there a way to change the following command to write all data from the csv file if the $alldates is empty/not defined and to write all data except the alldates filed if there already is a date defined?

exiftool -overwrite_original_in_place -sep ', ' -csv="/volume1/photo/data.csv" -@ /volume1/photo/files.txt

StarGeek

For all practical purposes, no, you can't really combine setting tags conditionally and non-conditionally in the same command.

You could put both in a single command separating each part with the -execute option, but that would still require two separate passes over all the files.  You might, at best, gain a couple seconds because exiftool doesn't have the start up overhead for the second pass, but the time savings of running it on thousands of files would be negligible.

And Phil probably could come up with a complex command that could do it, embedding Perl code in the tags with the Advanced formatting feature, but it wouldn't be easy to troubleshoot if something went wrong.  It would be further complicated by the fact that the AllDates shortcut could possibly cover up to six different tags, the three EXIF timestamps and the same name tags in XMP.

Overall, it's not something I would attempt.  Though Phil might come along and prove me wrong :)
* 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).

mbuzina

Thanks for the input - as complex as exiftool is, I thought maybe there is an abvious way that I am missing (like an equals operator that only writes on empty like -AllDates%="Value").

Phil Harvey

I'm with StarGeek on this one.  Even an advanced formatting expression (or better yet, the -filterw option) won't work because it would need to access values in the existing file, and these are not available when you are just writing tags from a CSV file.

The best way to do this is with 2 passes, but the 2nd pass may be sped up significantly:

1. Do the first pass to cover the more common case (eg. to avoid writing the dates if most files already contain date/time information), and use the -efile option to store the names of all files that fail the -if condition.  So the command will be something like this:

exiftool -if '$alldates' -efile4 failed.txt -csv=a.csv DIR

2. Run the second command on the files that failed the condition in the first command:

exiftool -@ failed.txt -csv=b.csv DIR

Of course, you'll have to prepare a second CSV file without date/time information to be used in the first command of my example.

- 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

Quote from: Phil Harvey on July 12, 2021, 08:34:49 AMwon't work because it would need to access values in the existing file, and these are not available when you are just writing tags from a CSV file.

Ah, yes.  I was just thinking generally that it would be complicated enough.  I forget to take into account the data was coming from a CSV.

QuoteThe best way to do this is with 2 passes, but the 2nd pass may be sped up significantly:

1. Do the first pass to cover the more common case (eg. to avoid writing the dates if most files already contain date/time information), and use the -efile option to store the names of all files that fail the -if condition.

Ah, I like that.
* 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).

mbuzina

Quote from: Phil Harvey on July 12, 2021, 08:34:49 AM
The best way to do this is with 2 passes, but the 2nd pass may be sped up significantly:

Of course, you'll have to prepare a second CSV file without date/time information to be used in the first command of my example.

- Phil

Great Idea! That is how I will do this, up to now I had thought of using a file without dates and updating all and then using one with dates updating with the if command. I did not know the efile4 option! Thanks

mbuzina

Just to let you know, it seems to be work. I am now at the first run, updating 17622 of 107754 files (!) It will take a little bit, about 24h is my estimate. Command like this:
exiftool -progress -overwrite_original_in_place -if '$alldates' -efile4 /volume1/photo/failed.txt -sep ', ' -csv="/volume1/photo/shared.csv" -@ /volume1/photo/share.txt | tee exif.log &

and the second run will be
exiftool -progress -overwrite_original_in_place -sep ', ' -csv="/volume1/photo/shared_dates.csv" -@ /volume1/photo/failed.txt | tee exif.log &