Hello.
I have a one-off need to extract part of many Windows 10 JPG photo filenames, and copy them into an Exif tag, but unfortunately I'm not up to speed with Regex yet.
I use a "mildly" random identifier in my photo filenames that always looks like this: [PIXxxxxxx], which makes for easy searching.
The filenames do not contain any foreign or unusual characters, but the [PIXxxxxxx] could appear anywhere in the filename.
Here's an example Filename...
This is a test [PIX817263] with the identifier located anywhere in the filename.jpg
Each filename contains [PIXxxxxxx] at an unknown location in the filename, and there are always 6 numerals after "[PIX" represented here as xxxxxx, that are random, ending with a "]".
So, what ExifTool Regex expression would I use to copy the [PIXxxxxxx] (with the brackets included) into (for example) the JPEG Comment tag (ie. comment) for each individual file in a Windows folder?
In summary, just to be clear, using the example I gave above, I would like to have [PIX817263] placed into the Comment tag for that particular jpg file.
I know I could study Regex and finally learn how to do it, but I'm very short on time, and it is only a one-off situation. Can any REGEX experts help please?
Regards,
-Paul
ps. There's no need to explain any examples you may give, unless you want to!
Once I've tested the output, I'll happily try and work backwards to gain an understanding at how the Regex expression works. Thanks!
The brackets are special characters, so they have to be escaped. PIX is a straight match, though if there is the possibility of a lower/mixed case pix, then that needs to be taken into account. Digits match with \d and the fact that there are six of them can be matched by adding {6}.
So to copy that into the Comment field, you could use
"-Comment<${Filename;m/(\[PIX\d{6}\])/;$_=$1}"
This captures the string you want and replaces the value of Filename with the captured string. This is case sensitive, so if you need it to be case insensitive, add an i after the last slash and before the semicolon.
I will advise, though, that the jpeg Comment field is fragile and there are lots of software out there that will overwrite it.
StarGeek. Thank you so much! You are a legend in your own time ;)
That worked perfectly!
Yes, I have the PIX as always Uppercase, and I was only using the Comment tag as an easy example, and I'll be using other tags to safely store it away. Thanks for your advice. I wasn't expecting an answer so soon!
-Paul :)
StarGeek. Following on from this, I've got 2 similar but separate slightly more complex scenarios now, that I hope you may also be able to help me with.
Still using the Regex code as before, and in the same operation, how would it need to be modified, to allow the following:
1). I may want to append some simple text to the copied tag. This text would be the same for a particular folder of photos. So, let's say (as a test) I wanted to add the phrase "Test 123 " in front of all of my PIX ids, and " xyz" to the end.
So, using my previous example, instead of just [PIX817263],
I'd end up with the tag Comment containing:Test 123 [PIX817263] xyz
------------------------------------------------------------
but ideally this following scenario is what I'll be requiring...
2). I have the initials LW in a tag called "OwnerName".
I'd like to append that (ie. "LW ") to the front of the PIX id.
ie. I'd end up with the tag Comment containing:LW [PIX817263]
I've experimented a bit with this, but I'm not making much progress thus far.
Regards,
-Paul
This shouldn't be too hard:
To add some text to the Comment tag: exiftool "-comment<${comment; $_ = 'PUX ids ' . $_ . ' TEXT'}" FILE
To the text from OwnerName to the Comment: exiftool "-comment<${comment; $_ = $ownername . ' ' . $_}" FILE
(the . is the Perl string concatenation operator)
Hmmm. Neither of those are working for me Hayo Baaan.
In Scenario #1, I want the PIX id to be extracted from the filename, and copied to the tag Comment, with the beginning and end phrases added.
So, from my first posted example (using text "Test 1 2 3" and "xyz"):
This is a test [PIX817263] with the identifier located anywhere in the filename.jpg
I would end up with Comment tag: Test 123 [PIX817263] xyz
I'm guessing from your example, that the concatenation simply must to be done in a secondary step from the example that StarGeek quoted??? If that's the case, then that's fine, but it might be easier for me to understand if you could please show me the exact usage, using my example here.
------------------------------------------------------------
As for Scenario #2, with ownername tag="LW" I tried:
exiftool "-comment<${comment;$_=$ownername.' '.$_}" FILE
but it didn't end up modifying the comment tag.
Hi Paul,
Try this:
"-Comment<Test 123 ${Filename;m/(\[PIX\d{6}\])/;$_=$1} xyz"
You may replace "Test 123" with "$ownername" to insert the value of the OwnerName tag in place of "Test 123". In the case where OwnerName doesn't exist, you can fall back to a default (eg. "Default Name") like this:
exiftool "-Comment<Default Name ${Filename;m/(\[PIX\d{6}\])/;$_=$1} xyz" "-Comment<$ownername ${Filename;m/(\[PIX\d{6}\])/;$_=$1} xyz" DIR
- Phil
Thanks Phil!
That solved it :)
Much appreciated all of you for your help. Now I really can get to work. I only have a mere 43167 photos to process. Ah fun. :-\
Ok. So one final thing, (and it's only minor in that I'm just trying to understand the "why?", and I'm sure it's been discussed many times before),... and, I'm guessing it has to do with the default order of ExifTool processing...
(Let's assume that the OwnerName tag starts off with a value of 'MD').
If I then use the following command to modify 3 tags, setting the new OwnerName to 'LW',
exiftool -OwnerName=LW "-Comment<$OwnerName ${Filename;m/(\[PIX\d{6}\])/;$_=$1}" "-Number<${Filename;m/(PIX\d{6})/;$_=$1}" FILE
I find that the old OwnerName of MD will be used in the new Comment tag instead of the new OwnerName of LW.
ie. The result is that...
tags...
OwnerName now contains: LW
Comment now contains: MD [PIX817263] <-- I expected LW [PIX817263]
Number now contains: PIX817263
So, my question is... Is there a simple way around this apart from splitting the commands into 2? like this...
exiftool -OwnerName=LW FILE
exiftool "-Comment<$OwnerName ${Filename;m/(\[PIX\d{6}\])/;$_=$1}" "-Number<${Filename;m/(PIX\d{6})/;$_=$1}" FILE
which does give the correct results as follows...
tags...
OwnerName now contains: LW
Comment now contains: LW [PIX817263]
Number now contains: PIX817263
ps. It's not a big problemo if I have to use the double command method. It just would be a bit simpler to use with some of the GUI programs, if I could just use the single one line command.
[EDIT: I just read this: FAQ 22 (https://exiftool.org/faq.html#Q22) so I guess that kind of explains it]. :o
Phil... You can just answer me with Read FAQ 22 (https://exiftool.org/faq.html#Q22) if that does apply in this situation. I'm guessing it does. So 2 command lines it is! :-\
pps. Even so... I still want it in one :'(
I'm glad you found FAQ 22.
You can do it in one line very easily:
exiftool -OwnerName=LW "-Comment<LW ${Filename;m/(\[PIX\d{6}\])/;$_=$1}" "-Number<${Filename;m/(PIX\d{6})/;$_=$1}" FILE
Oh. I see what I was doing. D'oh! lol. If the new value is already known then yeah, there's obviously no need to reload it indirectly. :-[
I blame Regex. It has that effect on my brain.
Thanks again Phil. ExifTool is brilliant!
Using this...
"-Comment<LW ${Filename;m/(\[PIX\d{6}\])/;$_=$1}"
I just noticed that the output tag will contain this: LW m/(\[PIX\d{6 if the filename does not contain one of my PIX ids. (Ideally every photo filename should contain a PIX id, but there are some I haven't got around to updating just yet).
How would I go about making the tag just contain "LW" or "LW " ? (Note: Blanks/Spaces don't concern me).
... or perhaps even better would be an error code inserted into the tag like "LW NO PIX ID"
To keep things simple, it doesn't really matter to me what the tag would contain upon lack of a PIX id, as long as it doesn't appear as gobbledegook like before, as it will be visible on a TV screen, overlaid onto the photo.
Right. Try this:
exiftool -OwnerName=LW "-Comment<LW ${Filename;$_ = m/(\[PIX\d{6}\])/ ? $1 : 'NO PIX ID'}" "-Number<${Filename;$_ = m/(PIX\d{6})/ ? $1 : 'NO PIX ID'}" FILE
- Phil
Edit: Fixed incorrect double quote. ooops
Yep. That works!
You are a genius, Sir.
Thanks Phil
OK. If I can just add a quickie to this posting. Hopefully it is an easy one...
I just need a quick & dirty regex expression to copy the filename into the comment tag without the known extension ".jpg", so there is no need to test for any other possibilities concerning uppercase, spaces, unusual characters ,etc, etc.
In other words, it just has to simply chop off the last 4 characters, and do nothing else, but copy all the characters of the Windows 10 filename before the".jpg" into the comment tag.
I know there are config files, etc, but I just want to use it here where the extension is known to always be ".jpg"
eg. Filename is:This is a test.jpg
I would like the comment tag to contain:This is a test
Thanks,
Paul
Grab the example config (https://exiftool.org/config.html) file and save it in the same directory as exiftool as .ExifTool_config. That gives you a new tag called BaseName.
Thanks StarGeek, but I was hoping to avoid having to use a config file (for now at least).
Is there no other way?
Also, is there an easy regex expression that would simply chop off the first 20 characters of the filename and store the remainder in the comment tag (...and of course... chop off the last 4 characters ie. the ".jpg" (without using a config file??)) ;)
eg. Filename:2019-06-14 10-32-12 This is a test.jpg
tag comment:This is a test
ps. This will probably be all that I need from exiftool and regex, as my needs are very simple, and I've almost done all the work that I needed with these handy tools.
I was hoping to avoid the use of a config file, for a couple of reasons. I use various GUI shells that mean that I'll have to remember to copy them to various folders, and most importantly also I'd love to see and learn the regex expressions that would enable these operations. :)
Quote from: mpegleg on June 14, 2019, 11:42:00 PM
Thanks StarGeek, but I was hoping to avoid having to use a config file (for now at least).
Config files rock. My base config file is about 1,800 lines long and I have multiple specialty config files for various, rarely used data.
But
Basename the standard answer because it's easy and less prone to mistakes.. You can lift the code directly from the example config, but I usually like to do something like this:
${Filename;s/\.[^.]*$//}To chop the first 20 characters would be
${Filename;s/^.{20}//}Combined would be
${Filename;s/^.{20}//;s/\.[^.]*$//}
Perfecto!
Thanks again StarGeek.
Yes, I know where you're coming from with the use of Config files, and I'll probably get into using them at a later date, but just for now I really wanted to know the base regex code that would achieve these simple operations. Now you've done that for me.
Wonderful :)
-Paul
ps. I use ExifMixer (http://www.moonsoftware.com/exifmixer.asp) to store all of my ExifTool and Regex chained operations, so I guess that's kind of like using a config file, but I can see where config files could simplify it all.
... and if I could just ask one more favo(u)r please...
What Regex code would I use (once again without using a config file) to copy filename contents to the comment tag, minus my PIX ID and EXT?...
In other words I'd like 12 characters removed beginning with "[PIX".
(Obviously that includes removing either the the leading space before the "[", or the trailing space after the "]").
It's kind of a combination/reversal of all of the previous scenarios,...
Note: As before, only [PIXxxxxxx] is constant, yet it may appear anywhere in the filename.
eg.
Filename:Test 123 [PIX817263] xyz.jpg
I want to end up with the comment tag containing:Test 123 xyz
I'm just not sure how to combine all of the Regex parts together.
Hopefully after this Regex 101 workout I should be able to complete most other basic scenarios on my own. 8)
Thanks again.
-Paul
In the first example, that used a regex match and capture. Instead of matching, you would just substitute with nothing.
${Filename;s/\[PIX\d{6}\] //}
Removed the parenthesis (the capture), changed the m (match) to s (substitute), added the extra space at the end of the original match, and then a final slash added to the end. The pattern for substitution is s/SEARCHPATTERN/REPLACE/ Here, since REPLACE is empty, the pattern is basically removed.
Heading to bed now, so that's all outta me for now.
So combined that would be...
${Filename;s/\[PIX\d{6}\] //;s/\.[^.]*$//}
That works.
Thanks again for all your help StarGeek (and Phil of course!)
G'nite! It's the middle of the day over here in oz! :)
Greetings from Sydney mpegleg, although I have not tried in ExifTool, the following single regex should work – the pipe | alternator allows for more than one match (i.e. match A "or" B, where the | pipe symbol is the "or"):
${Filename;s/\[PIX\d{6}\] |\.[^.]*$//}
Hi Stephen. Greetings from Perth!
I tried your Regex example, but unfortunately it doesn't remove the ".jpg" extension. The tag had the correct content, but it still had the extension included.
The example that I constructed with StarGeek's help did the job. Almost. Unfortunately it still doesn't remove the PIX id if the [PIXxxxxxx] has nothing immediately after it, just before the .jpg
So this filename will work:Test 123 [PIX123456] .jpg <---ie. it has a space (or anything else) just before the extension.
but this doesn't:Test 123 [PIX123456].jpg
--------------------
ps. * Just on an unrelated side-note for anyone using Windows 10, beware of the icon enhancement utility called SageThumbs (https://www.cherubicsoft.com/en/projects/sagethumbs). I've spent the better part of the day trying to sort out why I kept getting continual Windows Blue Screens of Death (BSODs). These only started today, so perhaps an auto Windows Update has stuffed things up. Not nice. Luckily with Windows 10, I rarely get BSODs. Apparently after much uninstalling of apps, doing image restores, etc, I finally tracked it down to this utility. Useful that it is, it just isn't worth the headaches that it causes, and it r e a l l y slows down the loading of folders with many images.
Quote from: Stephen Marsh on June 15, 2019, 09:48:01 AM
${Filename;s/\[PIX\d{6}\] |\.[^.]*$//}
The thing to remember here is that it will only do the first match. If you want it to do both, you need to add the g (global) modifier
${Filename;s/\[PIX\d{6}\] |\.[^.]*$//g}I haven't tested it though
Quote from: mpegleg on June 15, 2019, 10:28:54 AM
Unfortunately it still doesn't remove the PIX id if the [PIXxxxxxx] has nothing immediately after it, just before the .jpg
That's because regex has to be very exact. You have to try and figure out all the edge cases ahead of time. but in this case, it's pretty easy. There may or may not be a space, for which there is the
? (match 0 or 1 of the previous character).
So either
${Filename;s/\[PIX\d{6}\] ?//;s/\.[^.]*$//}or
${Filename;s/\[PIX\d{6}\] ?|\.[^.]*$//g}should work.
Thanks again StarGeek.
I just tried that first example, and I'll stick with that. It worked well.
Cheers
-Paul
Thanks StarGeek, I did forget to include the global flag in my example, that's what comes from not testing in ExifTool! I tested using RegEx101 which by default has the G flag turned on (out of sight, out of mind). I know that ExifTool is fast and so is RegEx, so there is probably little to no practical performance hit running two sequential vs. a single RegEx.
I know it's unrelated but can I just ask a question here without writing a new topic, as I'm sure it's been asked before, and I feel it's going to make me look like a right ETn00b (which I am!), but I can't seem to find what seems would be so obvious.
So, please excuse my ignorance here, but I am very new to this whole ExifTool experience, and I realize the whole Tag naming thing is extremely complex...
but when I list the available tags with ExifTool, I get the "friendly tag names", but why doesn't it (or how do I?) list the actual tag names that I'd have to use to list those specific tags.
For example:
ExifTool (with no arguments entered) will list my old Panasonic Travel camera's tag details as follows:
Make : Panasonic <-- Ok, so here "make" is the same as the friendly tag name
Camera Model Name : DMC-TZ40 <-- but here, in any expressions, I'd have to already know that
I must use "model", and not "Camera Model Name"
Is it possible to do a list that would be along the lines of:
Actual Tag Name Friendly Tag Name Value
------------------- --------------------- ------
make Make : Panasonic
model Camera Model Name : DMC-TZ40
I hope that makes sense?! I just feel that I'm "missing" something here in my understanding... and I've looked at the FAQ's etc, but I'm sure I've missed that info somewhere.
ie. Not so much in my example here, but often the Friendly Name that is output, can often be very different to the tag name that I'd have to use in an ExifTool expression.
Feel free to just point me along to the relevant FAQ, documentation, or any applicable Forum Topic if possible.
-Paul
You are right:
exiftool DIRorFILE
results in "descriptions", not actual tag names. To get the tag names:
exiftool -s DIRorFILE
However the following may be a better approach:
exiftool -a -G1 -s DIRorFILE
https://www.exiftool.org/faq.html (#2, #3c)
https://exiftool.org/exiftool_pod.html
-a (-duplicates) Allow duplicate tags to be extracted
-G[NUM...] (-groupNames) Print group name for each tag
-s[NUM] (-short) Short output format
Therefore, a simple command may not reveal everything:
exiftool -tagname DIRorFILE
Worth noting, the same entry may be written to many different groups and tags, which is revealed with -a -G1 -s:
[IFD0] ImageDescription
[XMP-dc] Description
[IPTC] Caption-Abstract
This is often the case with programs that are writing to both current (XMP-dc) and legacy (IPTC) metadata fields/tags, such as with Adobe apps.
https://exiftool.org/TagNames/index.html
https://exiftool.org/TagNames/MWG.html
So you can write just using the "shorthand" tag name:
exiftool -subject='foo' DIRorFILE
To avoid being ambiguous, you can use both the group and tag to be very explicit, which should only be an issue if there were conflicting tag names in different groups... I personally often prefer to use the "longhand" version with both group and name:
exiftool -XMP-dc:Subject='foo' DIRorFILE
Stephen. Many Thanks.
I just knew there had to be a (ton of) switch(es) for it.
exiftool -a -G1 -s DIRorFILE is much more useful for me! Perfect.
All I need now is an ExifTool switch that will automatically turn on my coffee machine. Hmmm. Is there a (hidden?) switch for that? Probably... wouldn't surprise me... or if not... I'm sure Phil is working on it. exiftool -MakeCoffeeNow -lotsof "COFFEE" +MILK +SUGAR ;D
Ok. So here's one more slightly advanced scenario of an example of what I eventually want to do... (It might be a new Forum topic required. I just don't know yet what would be involved). It's so hard to search the forum for "date" threads.
I've had a quick look at the DateFmt options, but I don't think they handle more "friendly" longform month date styles like Jan, January, etc.
The reason firstly, is that I want to serve out and display my images on a TV with more friendly date options for my elderly folks who aren't so happy always reading 1940-06-04, etc.
------------------
Eg.
Let's say that I have a Window's JPEG image with the filename: "A sunny day at the seaside.jpg" with a DateTimeOriginal=1940-06-04 (...and note that I'm not concerned about obtaining and displaying the time).
Is there a way that I could have a comment tag created that would contain: "A sunny day at the seaside (June 4, 1940)"
------------------
Note: Thanks to you all, now that I'm up to speed with manipulating the rest of the filename, all I'm now interested in, is creating the "June 4, 1940" string sequence for any given DateTimeOriginal.
Just wondering if ExiFtool has that capability?
Would it require a config file, Regex, or other scripting to do it? ... or is it out of the scope of what is easily possible here?
ps. if it's not easily doable with ExifTool, that's ok, as I do have a backup way of doing it, whereby I can use Rename Expert (https://www.rename-expert.com/) to rename a temporary folder of files and then import those filenames into the tags, but it's a bit of a long way around, esp. with 1000's of photos in multiple folders.
You can use either the -d (dateFormat) option (https://exiftool.org/exiftool_pod.html#d-FMT--dateFormat) to change the date output globally or the DateFmt helper function (https://exiftool.org/exiftool_pod.html#Helper-functions) on individual tags. Either way you would use standard strftime notation (https://exiftool.org/filename.html#codes) to format it. There are one or two of those formats that windows doesn't support, I can't recall which, but the most useful ones still work in Windows.
You basic option would be
-d "%B %d, %Y"
but it does have the caveat that there will be leading zeroes. Your example would return June 04, 1940. You can strip those with regex, either inline or globally with -api "Filter=s/\b0+\B//g"
Examples:
"-Comment<${Filename;s/\[PIX\d{6}\] ?//;s/\.[^.]*$//} (${DateTimeOriginal;DateFmt('%B %d, %Y');s/\b0+\B//g})"
or
-d "%B %d, %Y" "-Comment<${Filename;s/\[PIX\d{6}\] ?//;s/\.[^.]*$//} (${DateTimeOriginal;s/\b0+\B//g})"
or
-d "%B %d, %Y" -api "Filter=s/\b0+\B//g" "-Comment<${Filename;s/\[PIX\d{6}\] ?//;s/\.[^.]*$//} (${DateTimeOriginal})"
Fun fact, this demonstrates the perl motto, TIMTOWTDI (Tim Toady) (https://en.wikipedia.org/wiki/There%27s_more_than_one_way_to_do_it).
Wow. Thanks StarGeek. That was quick.
Are there any advantages/disadvantages to using any particular one of those examples? Is any one of them more... "robust"?
Preferably the simplest one.
The first 2 worked as expected, but the 3rd one didn't do anything, although it did say the file was updated. I'm still checking the syntax... might be my fault....
Edit. Ah yes, it was my fault. I was using the wrong tag. I was testing with XPComment rather than comment. *slap face*
They all worked. So does any one have an advantage over the others? I guess I'll create some temporary folders and let them all rip, on a few thousand photos. We shall see :)
The Zen of Python (https://www.python.org/dev/peps/pep-0020/): There should be one-- and preferably only one --obvious way to do it. :P
...but to be honest, I'm so glad there isn't!
I would prefer the first one since that allows you to combine it more easily with (setting) other tags; the second one fixes the output of all dates while the third would apply the "filter" to all tags.
OK. Good, because that's the one I've currently got doing the hard yards, and it's working like a charm, so I guess I'll stick with that.
As my father used to say... "If it ain't broke... don't fix it".
I'm still taking baby steps with this.
My next scenario to speed up the renaming of some of my photos is to use part of the current directory name. So it combines what we have done previously, but now using part of the current directory name.
This is the Directory naming structure I have at present...
Eg.
I have many Windows folders similar to this. For this example, it contains 3 files as follows:
(Not real photos. But I have created them to test) :o
W:/Photos/John/2018/2018-12-25 Santa's Misfortune/
2018-12-25 02-35-01 [PIX854974] This is a photo of Santa coming down the chimney.jpg
2018-12-25 02-36-42 [PIX344563] This is a photo of Woofy biting Santa's leg.jpg
2018-12-25 03-14-22 [PIX102673] This is the next photo of Santa being treated in hospital.jpg
I would like the the 3 photo's command tags to contain :
Santa's Misfortune - This is a photo of Santa coming down the chimney (Dec 25, 2018)
Santa's Misfortune - This is a photo of Woofy biting Santa's leg (Dec 25, 2018)
Santa's Misfortune - This is the next photo of Santa being treated in hospital (Dec 25, 2018)
Who's up to the challenge? Note the shortened form of the MONTH required. The date should be extracted from DateTimeOriginal.
Thanks in advance to all of you for your time & patience. I'm learning heaps from these practical exercises, and I'm sure it will be very useful to other ETn00bs. Working through all the detailed documentation is taxing, yet these practical examples are so much easier for me to get my head around. :)
This should work on Mac/Linux:
exiftool '-comment<${directory; use Cwd "abs_path"; $_ = abs_path($_); $_ =~ s/.*\///;} - ${filename; $_ =~ s/.*\] |\....$//g;} (${datetimeoriginal; DateFmt("%b %e, %Y");})' FILES
On Windows, use this (i.e. swap single and double quotes):
exiftool "-comment<${directory; use Cwd 'abs_path'; $_ = abs_path($_); $_ =~ s/.*\///;} - ${filename; $_ =~ s/.*\] |\....$//g;} (${datetimeoriginal; DateFmt('%b %e, %Y');})" FILES
Note: if the directory name doesn't come out right and contains the full path, replace $_ =~ s/.*\///; by $_ =~ s/.*\\//;
In above commands I use abs_path to allow use in e.g. the current directory, %b instead of %B for the abbreviated month name and %e instead of %d to get the day without leading 0.
The result on two of your files:
$ exiftool -comment *.jpg
======== 2018-12-25 02-35-01 [PIX854974] This is a photo of Santa coming down the chimney.jpg
[File] Comment : 2018-12-25 Santa's Misfortune - This is a photo of Santa coming down the chimney (Dec 25, 2018)
======== 2018-12-25 02-36-42 [PIX344563] This is a photo of Woofy biting Santa's leg.jpg
[File] Comment : 2018-12-25 Santa's Misfortune - This is a photo of Woofy biting Santa's leg (Dec 25, 2018)
Hayo Baan.
My result on Windows 10 using ExifMixer GUI was:
2018-12-25 Santa's Misfortune - This is the next photo of Santa being treated in hospital ()
I'd rather not have the leading date, and of course... the ending (), has no date??
...and using the CMD command window with a batch file:
2018-12-25 Santa's Misfortune - This is the next photo of Santa being treated in hospital (e, Y)
* I think it might have something to do with the length of the whole string... when combined with the long filepath and filename? EDIT: No. I had a truncation of the command only when I tried dragging and dropping onto a batch file.
Right, overlooked the fact you didn't want the date in the directory name included in the comment, that should be easily fixed:
exiftool "-comment<${directory; use Cwd 'abs_path'; $_ = abs_path($_); $_ =~ s/.*\///; $_ =~ s/^[0-9- ]*//;} - ${filename; $_ =~ s/.*\] |\....$//g;} (${datetimeoriginal; DateFmt('%b %e, %Y');})" FILES
As to why there's no date showing, that's really odd since a similar DateFmt worked for you before... Do the files in fact have a datetimeoriginal and did you really use the Windows version of the command including the double quotes surrounding the whole argument?
The fact that the batch file didn't show anything has to do with Windows interpreting %x as a variable, not a literal. BUT the quotes should have prevented that from happening.
Yes. I just tried the same files with StarGeek's example previously and the dates worked OK.
You have fixed the initial date showing, so we're almost there.
Santa's Misfortune - This is the next photo of Santa being treated in hospital (e, Y)
I think that Windows interpolates "%" inside quotes. So you must double all "%" characters in a Windows .bat file if you are running the command from there.
- Phil
Ok. I tried double quotes in the batch file...
Santa's Misfortune - This is the next photo of Santa being treated in hospital ()
OK. I did it! :)
I combined the first part of Hayo Baan's with (a very slightly modified version) of the last part of StarGeek's, and it worked! (I also obviously had to change the "B" to "b" to use the Month shortform).
So that means... Hayo+Geek=HayoGeek SUCCESS!!
exiftool "-comment<${directory; use Cwd 'abs_path'; $_ = abs_path($_); $_ =~ s/.*\///; $_ =~ s/^[0-9- ]*//;} - ${filename; $_ =~ s/.*\] |\....$//g;} (${DateTimeOriginal;DateFmt('%%b %%d, %%Y');s/\b0+\B//g})" FILE
comment tag now contains:
Santa's Misfortune - This is the next photo of Santa being treated in hospital (Dec 25, 2018)
Thank you all :) ps. Santa has recovered well.
----------------------------
EDIT: After a bit of reflection and tinkering with the code, I decided to go with this:
"-comment<${Filename;s/\[PIX\d{6}\] ?//;s/^.{29}//;s/\.[^.]*$//} [${directory;use Cwd 'abs_path';$_=abs_path($_);$_=~s/.*\///;$_=~s/^[0-9- ]*//;} - ${DateTimeOriginal;DateFmt('%b %d, %Y');s/\b0+\B//g}]" FILE
(Of course I need to remember to double up on the % signs, when used in a Windows batch file!)
So now,
W:\John\2018\2018-12-25 Santa's Misfortune\
2018-12-25 02-54-58 IMG_0125 [PIX343107] Santa falling down the chimney.JPG
2018-12-25 18-55-36 IMG_0126 After a long day at work, [PIX598541] Santa falls asleep.JPG
2018-12-25 19-02-22 IMG_0127 [PIX779251].JPG
will provide me with 3 comment tags containing:
Santa falling down the chimney [Santa's Misfortune - Dec 25, 2018]
After a long day at work, Santa falls asleep [Santa's Misfortune - Dec 25, 2018]
[Santa's Misfortune - Dec 25, 2018]
which better suits me, as I realize that most of my photos don't have any "friendly" text description (as in my 3rd JPG example), so the square brackets will alert me to that fact that the text I am seeing is a "Collection" Title, rather than a specific description of the photo. Perfect!
Excellent, so as it turns out, you only had to replace my %e with %d and then remove the leading zero in another regexp. I guess the Windows version of strftime (which is called underneath all this) doesn't have %e. You live and learn ;)
Hi. I'm locked out from modifying my own posts here, (as the time limit for edits has passed), so can one of the mods be so kind as to please edit it for me, as I realize that it won't work as is, under Windows. Strange thing is, it worked using ExifTool Mixer. :-\
Anyway, the minor (but important) correction required, is in my very last post.
-comment<"${Filename;s/\[PIX\d{6}\] ?//;s/^.{29}//;s/\.[^.]*$//} [${directory;use Cwd 'abs_path';$_=abs_path($_);$_=~s/.*\///;$_=~s/^[0-9- ]*//;} - ${DateTimeOriginal;DateFmt('%b %d, %Y');s/\b0+\B//g}]" FILE
should be:
"-comment<${Filename;s/\[PIX\d{6}\] ?//;s/^.{29}//;s/\.[^.]*$//} [${directory;use Cwd 'abs_path';$_=abs_path($_);$_=~s/.*\///;$_=~s/^[0-9- ]*//;} - ${DateTimeOriginal;DateFmt('%b %d, %Y');s/\b0+\B//g}]" FILE
I did some tests, and apparently the position of the double quotes at the start is very important here.
(In future I'll have to make sure I do a few more tests using cmd, batch and ExifMixer, before posting. These files were also on a mapped network drive, so that can obviously cause Windows path issues).
Many Thanks!
ps. I'll leave you all in peace now
Cheers,
Paul.
Yes, the position of the quotes is important or else the shell will interpret things differently (e.g. the < will be seen as input redirection, not as part of the argument to exiftool, when it not in quotes). Anyway, glad everything has worked out for you in the end.
Hi Hayo Baan.
Do you have the auth to modify that post, or is Phil the only one authorised to do that? I hate leaving bad code lying around that is clearly wrong. Some poor sod is likely to come across this thread, and cut & paste the example, and end up with a headache for nothing.
Can't you modify the post yourself? Afaik you should always be able to edit your own posts (I am on another forum that uses the same software and there I have edited post from years back)? Anyway, as moderator I was able to make the change (moved the double quote in front). Was that all that needed to be changed?
Well yes, I do normally modify my own posts (too many times. lol), but there must be a time limit, because the "Modify" button has disappeared on all my posts in this thread except for the last 2 I have just made. I noticed this before. I think the limit has been set for 24 hours or just under.
Thanks for changing it anyway. Yes that's all for now. I have another Regex question coming up soon. I'm just trying to figure it out myself first, but so far not having much success. Regex is hard (for n00bs). I'll keep working on it for now, and I'll ask if I can't figure it out.
I was pretty familiar with SMF Forum software. I was an admin of a site using it, but that was quite a few years ago, so I'm a bit out of touch with it. Yes you can set a time limit on how long people can make edits. I got "the time limit for edits has passed" message when I tried to use another tab that I had open, so I know that there is definitely a time limit set. (Perhaps the time limit has been set up in tandem with the number of member posts. From memory, you can set it up that way too). SMF Forum software has almost as many customisable options as ExifTool ! ;)
Cheers,
Paul
Ok. I surrender on this one. Regex is not much fun when you are sleep-deprived.
Anyway, I know it's some relatively easy Regex code (well "easy" when you know how!).
I use the term modx as a search term because it's pretty unique (as is PIX).
So, some of my "edited" photos contain the term "modx" somewhere in the filename.
Anything after the modx is for my eyes only, as it is only editing babble.
What I'd like to do, is strip [PIXxxxxxx] as before, (it may appear anywhere in the filename), but I also want to strip out the " modx" and anything after it, including the space character before the modx up to and including the filename extension.
Example filename:
I don't want this text but [PIX172643] I do want this text modx but I don't want this.jpg
so that the comment tag will only contain:
I do want this text
It would also have to take into account that sometimes the modx will not be in the filename. (Most of the time it won't be).
Assume that the PIX code will ALWAYS be somewhere in the filename, even at the very end, which should mean that only in this case, the comment tag should be forced empty, OR even better it could have "NO PIX ID" stored as an error flag, as I really want every single photo to have a PIX code.
*sigh* is that a brain drain or what? :-\
Thanks,
Paul
A regexp to only get the I do want this text part is: s/^(?:.*\[PIX\d+\]\s*)?((?:.(?!modx))*?)(?:\s*modx.*|\..{3,4}$)/$1/
The "hardest" part was to allow for the PIX and modx parts to be absent for that I made use of a negative look-ahead assertion ?! as well a non-greedy capture *?. I also allowed for 3 or 4 letter extensions. (and in case you wonder what ?: is, that means it is a non-capturing group, this makes it a bit faster and we don't care about the content anyway).
Of course, splitting this into two regexps would have been easier, but I liked a challenge ;)
To test this e.g. use exiftool "-testname<${filename; $_ =~ s/^(?:.*\[PIX\d+\]\s*)?((?:.(?!modx))*)(?:\s*modx.*|\....$)/$1/;}"
Thank Hayo. I'll test it out. Sorry, I added the bit to my post where I said... assume that PIX will ALWAYS be present, but... if it could flag an error, that would be even better.
If you need to change it, leave the other code as well because it's a very good learning exercise for me.
No, there's no change needed if PIX is non-optional (though in that case you can remove the (?: at the front and the )? at the end of (?:.*\[PIX\d+\]\s*)?, making it it a bit simpler).
There were a lot of errors produced, however the result was perfect in the first trial, but did not remove the "modx" in the 2nd and 3rd trials. I hope you can read the attached cmd screenshot. (You may need to download it)...
(http://s01.geekpic.net/dt-CNJF4B.png) (http://geekpic.net/pm-CNJF4B.html)
I just realised the first trial was missing a double-quote after the filename, but that one worked anyway, probably because I included the first double-quotes, and I was lucky that there were no other args or commands after the jpg.
Hmm, these errors indicate either you have a problem with your exiftool installation, or there's a typo in the code you used that makes the exiftool code trip (at a later point). Actually, given the "missing curly brace" perl error, that seems likely. Make sure, for instance, the double quotes aren't smart quotes; that will make things fail on the command-line.
Next time instead of posting a screenshot, simply copy/paste the content of the screen into a [ code ] [ /code ] block, that way I can copy and use the exact command you typed to see what I get here with that exact same command.
Quote from: Hayo Baan on June 17, 2019, 05:20:12 AM
Hmm, these errors indicate either you have a problem with your exiftool installation, or there's a typo in the code you used that makes the exiftool code trip (at a later point). Actually, given the "missing curly brace" perl error, that seems likely. Make sure, for instance, the double quotes aren't smart quotes; that will make things fail on the command-line.
I don't normally get all those error messages. It's pretty much the first time I've seen any of those. I can test it on another pc if necessary. I simply cut and pasted your code, and added the other bits. There's nothing fancy about my installation, and the exiftool.exe v11.51 file has simply been downloaded, unzipped, and dropped into the same folder along with those test images.
Quote
Next time instead of posting a screenshot, simply copy/paste the content of the screen into a [ code ] [ /code ] block, that way I can copy and use the exact command you typed to see what I get here with that exact same command.
EDIT: OK. I found how to cut and paste the text from the cmd windows. It's a bit different to normal windows.
Bear with me... I'll try to post the text here soon...
Filename:I don't want this text but [PIX172643] I do want this text modx but I don't want this.jpg
W:\Tests>exiftool -m -overwrite_original "-XPcomment<${filename; $_ =~ s/^(?:.*\[PIX\d+\]\s*)?((?:.(?!modx))*)(?:\s*modx.*|\....$)/$1/;}" "I don't want this text but [PIX172643] I do want this text modx but I don't want this.jpg"
Global symbol "$psiz" requires explicit package name (did you forget to declare "my $psiz"?) at Image/ExifTool/Photoshop.pm line 203, <EXIFTOOL_FILE> chunk 4.
syntax error at Image/ExifTool/Photoshop.pm line 203, near "2) "
Global symbol "$psiz" requires explicit package name (did you forget to declare "my $psiz"?) at Image/ExifTool/Photoshop.pm line 203, <EXIFTOOL_FILE> chunk 4.
Global symbol "$len" requires explicit package name (did you forget to declare "my $len"?) at Image/ExifTool/Photoshop.pm line 204, <EXIFTOOL_FILE> chunk 4.
Global symbol "$psb" requires explicit package name (did you forget to declare "my $psb"?) at Image/ExifTool/Photoshop.pm line 204, <EXIFTOOL_FILE> chunk 4.
Global symbol "$data" requires explicit package name (did you forget to declare "my $data"?) at Image/ExifTool/Photoshop.pm line 204, <EXIFTOOL_FILE> chunk 4.
Global symbol "$data" requires explicit package name (did you forget to declare "my $data"?) at Image/ExifTool/Photoshop.pm line 204, <EXIFTOOL_FILE> chunk 4.
syntax error at Image/ExifTool/Photoshop.pm line 205, near "}"
Global symbol "$raf" requires explicit package name (did you forget to declare "my $raf"?) at Image/ExifTool/Photoshop.pm line 206, <EXIFTOOL_FILE> chunk 4.
Unmatched right curly bracket at Image/ExifTool/Photoshop.pm line 208, at end of line
Image/ExifTool/Photoshop.pm has too many errors.
Compilation failed in require at (eval 35) line 2, <EXIFTOOL_FILE> chunk 4.
Can't find table Image::ExifTool::Photoshop::Main
1 image files updated
W:\Tests>
Result:I do want this text <-- That's good.
Filename:I don't want this text but [PIX172643] modx but I don't want this.jpg
W:\Tests>exiftool -m -overwrite_original "-XPcomment<${filename; $_ =~ s/^(?:.*\[PIX\d+\]\s*)?((?:.(?!modx))*)(?:\s*modx.*|\....$)/$1/;}" "I don't want this text but [PIX172643] modx but I don't want this.jpg"
Global symbol "$psiz" requires explicit package name (did you forget to declare "my $psiz"?) at Image/ExifTool/Photoshop.pm line 203, <EXIFTOOL_FILE> chunk 4.
syntax error at Image/ExifTool/Photoshop.pm line 203, near "2) "
Global symbol "$psiz" requires explicit package name (did you forget to declare "my $psiz"?) at Image/ExifTool/Photoshop.pm line 203, <EXIFTOOL_FILE> chunk 4.
Global symbol "$len" requires explicit package name (did you forget to declare "my $len"?) at Image/ExifTool/Photoshop.pm line 204, <EXIFTOOL_FILE> chunk 4.
Global symbol "$psb" requires explicit package name (did you forget to declare "my $psb"?) at Image/ExifTool/Photoshop.pm line 204, <EXIFTOOL_FILE> chunk 4.
Global symbol "$data" requires explicit package name (did you forget to declare "my $data"?) at Image/ExifTool/Photoshop.pm line 204, <EXIFTOOL_FILE> chunk 4.
Global symbol "$data" requires explicit package name (did you forget to declare "my $data"?) at Image/ExifTool/Photoshop.pm line 204, <EXIFTOOL_FILE> chunk 4.
syntax error at Image/ExifTool/Photoshop.pm line 205, near "}"
Global symbol "$raf" requires explicit package name (did you forget to declare "my $raf"?) at Image/ExifTool/Photoshop.pm line 206, <EXIFTOOL_FILE> chunk 4.
Unmatched right curly bracket at Image/ExifTool/Photoshop.pm line 208, at end of line
Image/ExifTool/Photoshop.pm has too many errors.
Compilation failed in require at (eval 35) line 2, <EXIFTOOL_FILE> chunk 4.
Can't find table Image::ExifTool::Photoshop::Main
1 image files updated
W:\Tests>
Result:modx but I don't want this <-- should be blank
Filename:I don't want this text but [PIX172643] modx.jpg
W:\Tests>exiftool -m -overwrite_original "-XPcomment<${filename; $_ =~ s/^(?:.*\[PIX\d+\]\s*)?((?:.(?!modx))*)(?:\s*modx.*|\....$)/$1/;}" "I don't want this text but [PIX172643] modx.jpg"
Global symbol "$psiz" requires explicit package name (did you forget to declare "my $psiz"?) at Image/ExifTool/Photoshop.pm line 203, <EXIFTOOL_FILE> chunk 4.
syntax error at Image/ExifTool/Photoshop.pm line 203, near "2) "
Global symbol "$psiz" requires explicit package name (did you forget to declare "my $psiz"?) at Image/ExifTool/Photoshop.pm line 203, <EXIFTOOL_FILE> chunk 4.
Global symbol "$len" requires explicit package name (did you forget to declare "my $len"?) at Image/ExifTool/Photoshop.pm line 204, <EXIFTOOL_FILE> chunk 4.
Global symbol "$psb" requires explicit package name (did you forget to declare "my $psb"?) at Image/ExifTool/Photoshop.pm line 204, <EXIFTOOL_FILE> chunk 4.
Global symbol "$data" requires explicit package name (did you forget to declare "my $data"?) at Image/ExifTool/Photoshop.pm line 204, <EXIFTOOL_FILE> chunk 4.
Global symbol "$data" requires explicit package name (did you forget to declare "my $data"?) at Image/ExifTool/Photoshop.pm line 204, <EXIFTOOL_FILE> chunk 4.
syntax error at Image/ExifTool/Photoshop.pm line 205, near "}"
Global symbol "$raf" requires explicit package name (did you forget to declare "my $raf"?) at Image/ExifTool/Photoshop.pm line 206, <EXIFTOOL_FILE> chunk 4.
Unmatched right curly bracket at Image/ExifTool/Photoshop.pm line 208, at end of line
Image/ExifTool/Photoshop.pm has too many errors.
Compilation failed in require at (eval 35) line 2, <EXIFTOOL_FILE> chunk 4.
Can't find table Image::ExifTool::Photoshop::Main
1 image files updated
W:\Tests>
Result:modx <-- should be blank
!!! It was those random images I chose that are causing the errors!
Stand by.
I'm running some tests on other images... and so far no errors...
Hayo. It worked on all tests!
I'm sorry I didn't test other images before. It still doesn't explain why those particular images caused the errors, but I get no errors with the new images I just tried and the results were as hoped.
Thanks, and sorry!
-Paul
ps. Looking at the image I chose, (and I'd just copied it and renamed for the test). It turns out it was a particularly bad choice. I never even looked at the picture to be honest, but now I realise it was a "special" case image. One that has been heavily manipulated by my Uncle and me. It's a really poor quality image and not one that I would normally show anyone. I think it was one I had actually flagged for deletion, but I like keeping cr*p" images just for this very good test case! You can have a copy if you want for testing. It appears to be a very blurry old image of a German castle. My Uncle took it while holidaying there. It had been cropped heavily, and I think I have Photoshopped it recently too.
Right, so it looks like you found images that cause exiftool to trigger a syntax error in the code! Can you share such an image?
Also, there was indeed an error in my regexp that would not leave the text blank in the two last examples. You should be using s/^(?:.*\[PIX\d+\]\s*)?((?:(?!modx).)*)(?:\s*modx.*|\....$)/$1/
as the regular expression (negative look-ahead assertion in front of the . instead of after it, this allows for an empty text part for what you want to keep).
Yes. But the picture is REALLY CR*P, so don't laugh. It's one my Uncle took (true. Not me!) while in Germany, and has been heavily manipulated. Could be interesting for a debug exercise for you all, so once I check that's there's nothing too personal in the Exif tags, I won't modify it, and I'll upload it.
OK. So here is the culprit!... and I notice this is the resized down/modified version that I normally show on the TV. I'll check the original in a minute once I find it. I can't use the PIX ids to search because I made these test ones up. lol. I'm sure it will cause the same errors. Interesting. I'll upload that too when I find it...
Aha. Looking at the original filename... this probably explains a lot!
2010-08-12 08-48-11 IMG_5588 [PIX579159] (original full-res photo was damaged) modx1
It's now coming back to me. I now remember it wouldn't load into Photoshop, or any other image editor and I ended up using some way of trying to fix it. Obviously I only half completed that job!
Here's the "not really an original at all" original. It's actually a very heavily downsized wreck of a photo. lol
EDIT: I just tried to download it and I got this: our attachment has failed security checks and cannot be uploaded. Please consult the forum administrator
So it obviously has a LOT of issues with it. It's also only 181 kB ! whereas all the other full-size original images in the same folder average about 4 to 5 MB. I do remember when I first saw it, and saw the very small size... l was left thinking "Where'd this oddball image come from?", but it is in sequence with the other images.
Quote from: mpegleg on June 17, 2019, 06:25:46 AM
OK. So here is the culprit!... and I notice this is the resized down/modified version that I normally show on the TV. I'll check the original in a minute once I find it. I can't use the PIX ids to search because I made these test ones up. lol. I'm sure it will cause the same errors. Interesting. I'll upload that too when I find it...
Nope, I don't get the perl errors you get; the file is updated just fine. Note though that it indeed has quite some (very minor) issues:
$ exiftool -validate -warning -a -G0:1 "I don't want this text but [PIX172643] I do want this text modx but I don't want this.jpg"
[ExifTool] Validate : 8 Warnings (all minor)
[ExifTool] Warning : [minor] Non-standard ExifIFD tag 0xea1c Padding
[ExifTool] Warning : [minor] Non-standard IFD0 tag 0xea1c Padding
[ExifTool] Warning : [minor] Fixed incorrect URI for xmlns:MicrosoftPhoto
[ExifTool] Warning : [minor] IFD0 tag 0x0100 ImageWidth is not allowed in JPEG
[ExifTool] Warning : [minor] IFD0 tag 0x0101 ImageHeight is not allowed in JPEG
[ExifTool] Warning : [minor] IFD0 tag 0x0102 BitsPerSample is not allowed in JPEG
[ExifTool] Warning : [minor] IFD0 tag 0x0106 PhotometricInterpretation is not allowed in JPEG
[ExifTool] Warning : [minor] IFD0 tag 0x0115 SamplesPerPixel is not allowed in JPEG
It updated fine though:
$ exiftool -m -overwrite_original '-XPcomment<${filename; $_ =~ s/^(?:.*\[PIX\d+\]\s*)?((?:(?!modx).)*)(?:\s*modx.*|\....$)/$1/;}' "I don't want this text but [PIX172643] I do want this text modx but I don't want this.jpg"
1 image files updated
$ exiftool -G0:1 -a -XPcomment "I don't want this text but [PIX172643] I do want this text modx but I don't want this.jpg"
[EXIF:IFD0] XP Comment : I do want this text
(had to switch the double quote to single on my Mac)
Yes, so I wouldn't recommend wasting too much more time on this image. It was corrupted to start with. Why out of my 40000+ images did I have to choose that particular one to test with! ::) *slap!*
Yes, but it would still be nice to have the file since it triggers an error in the exiftool code. If you can't post it here (perhaps zipping it works), you can also send it to me info@hayobaan.nl.
Your wish is my command...
Don't know why I didn't think of zipping it. I hope a RAR is ok?
Also I just searched through my Archive backups. This one has been untouched since it was last messed around with in 2010...
It's obviously still not the Absolute "fresh from the camera memory card" corrupted original, but it's the oldest one I could find.
To get all of those Perl errors in Photoshop.pm, your installation must be corrupted somehow. Delete the temporary files (C:\Users\USER\AppData\Local\Temp\par-xxx) and try again.
- Phil
I'll do that Phil, just to be sure, but I doubt anything is corrupted with ExifTool apart from that %$#!#$ photo. I'm not getting any errors on any other images. Like I was saying to Hayo Baan, it was just a very poor random choice of an image to use for testing with. Pure chance. Perhaps I should have deleted it.
It was a photo that had been marked for deletion because I couldn't originally load it into any photo editor, and I managed to get it to a state where I could view it, but I knew it was still corrupted. Anyway... I'm off to delete the temps....
Indeed, looks like a corrupted install at your end; that file gives me no issues at all, even validation only gives a very minor warning: [minor] Odd offset for IFD0 tag 0x0132 ModifyDate
If you aren't getting errors with other images it is because they don't contain Photoshop information. It is the Photoshop module that is corrupted.
- Phil
Yes. Of course you guys were right! I just deleted the Temp files, and restarted.
You may have read one of my posts a while back in this thread where I was talking about having multiple BSODs "Blue screens of Death". Well. I guess things really did get pretty screwy. I also did a successful recover from a Acronis True Image restore, which is why I didn't think anything could be too screwed up.
Anyway, I just tried that same file again.. and guess what. No Errors! :-[
Thanks again, and sorry for all the drama. I'll slink off somewhere and hide now :)
Thanks Phil,
...and Hayo... thanks for the help. I haven't had time to fully work other tests on your code yet, but I will.
Cheers,
-Paul
ps. I think I'll reload another earlier True Image restore going back about a week or so, just to be on the safe side. I don't really don't feel that my system is stable.
I just thought I would add a quick little note. Yesterday I did a Windows sfc scannow system file scan and it DID find some corrupted system files. It fixed them and I moved on and didn't think much more of it, Except... I forgot... it only fixes Windows system files nothing else! So any apps like ExifTool could have had corrupted files, and it wouldn't know. Lesson learnt. Always restore after a BSOD.
So I'm off to do a full system restore now. Over and out. See you on the other side. :)
ps. It doesn't take long with SSD. I'll probably be back in about 1/2 hr. *fingers crossed*
I'm b a a c k. Who said time travel wasn't possible?!
Luckily I have about 3 months worth of daily restore images, so I jumped back a week, which should be well before I started getting the BSODs in the last few days caused by SageThumbs. Grrr. I'll never run that utility again. Uninstalled & DELETED!
I should have known better, because a couple of other utilities had also been behaving strangely in the last few days as well.
I just did a system file check. No errors.
I just cleared the TEMP folder, and re-installed ExifTool, so I think we're good to go.
I'll do a thorough check of Hayo Baan's code tomorrow, but it's looking good so far.
Thanks again Hayo Baan.
ps. Thanks again Phil for suggesting that my ExifTool install was corrupt. It appears it was. That makes perfect sense now. When I did my previous system image restore, obviously I didn't go back far enough, (I only went to the previous day's backup). When I think about it... the BSODs had been occuring over a period of about 3 days.
Ok. So I decided to give Hayo's corrected code a quick go, and yep. It all seems to work well. The examples of where it should have ended with an empty tag, did just that. Also, there's no ExifTool error messages now with that corrupted image.
So once again.
Thanks very much.
-Paul
Excellent, great to hear all is well now!
Hayo, using parts of your (+ StarGeek's, and Phil's) code:
"-XPcomment<${filename; $_ =~ s/^(?:.*\[PIX\d+\]\s*)?((?:(?!modx).)*)(?:\s*modx.*|\....$)/$1/;} [${directory; use Cwd 'abs_path';$_ = abs_path($_); $_ =~ s/.*\///; $_ =~ s/^[0-9- ]*//;}. ${DateTimeOriginal;DateFmt('%Y');s/\b0+\B//g}]"
I was able to achieve this very good result:
(http://s01.geekpic.net/dt-NGY0IE.png) (http://geekpic.net/pm-NGY0IE.html)
So, it's very close to being perfect for my needs, if only those annoying extra spaces can be made to vanish into the ether.
-Paul
Add this in an advanced formatting expression to remove extra spaces: ;s/ +/ /g
- Phil
Thanks Phil. Sorry but I'm a bit dense with all this still. Do you mind popping that into my code so I can see exactly where it should go?
Thanks :)
"-XPcomment<${filename; $_ =~ s/^(?:.*\[PIX\d+\]\s*)?((?:(?!modx).)*)(?:\s*modx.*|\....$)/$1/;s/ +//g} [${directory; use Cwd 'abs_path';$_ = abs_path($_); $_ =~ s/.*\///; $_ =~ s/^[0-9- ]*//;}. ${DateTimeOriginal;DateFmt('%Y');s/\b0+\B//g}]"
Edit: Hmmm. This will remove extra spaces within the file name, but not at the end. So maybe you need this:
"-XPcomment<${filename; $_ =~ s/^(?:.*\[PIX\d+\]\s*)?((?:(?!modx).)*)(?:\s*modx.*|\....$)/$1/;s/ +//g;s/ +$//} [${directory; use Cwd 'abs_path';$_ = abs_path($_); $_ =~ s/.*\///; $_ =~ s/^[0-9- ]*//;}. ${DateTimeOriginal;DateFmt('%Y');s/\b0+\B//g}]"
The basic setup for the advanced formatting feature is like this:
${TAGNAME;<perl code>;<perl code>;...;}
Each snippet of perl code is separated by a semicolon and the whole thing is closed by a brace.
You can just pop the new code at the end before the last brace. You just have to make sure there is a semicolon before it to separate it from the previous code.
Sorry, this whole thing blew up (2 additional full pages) since I last looked and that code is getting too big for me to easily decipher. This is actually a case where I would seriously suggest starting config file and creating a user defined tag out of it.
YAY!!!! Thank you Phil, StarGeek and Hayo Baan.
Yes, that first one Phil didn't work. I posted a reply, but quickly deleted it when I saw your edited post.
So, all good now.
Time for me to hit the sack. Midnight downunder here, and I can hardly keep my eyes open, but I can go to sleep deeply satisfied now. :) ;D
Many many thanks. You've all made my life so much easier. My parents thank you as well, because they're the ones that will truly benefit when I show them all the nicely captioned photos.
G'nite!
"-XPcomment<${filename; $_ =~ s/^(?:.*\[PIX\d+\]\s*)?((?:(?!modx).)*)(?:\s*modx.*|\....$)/$1/;s/ +//g;s/ +$//} [${directory; use Cwd 'abs_path';$_ = abs_path($_); $_ =~ s/.*\///; $_ =~ s/^[0-9- ]*//;}. ${DateTimeOriginal;DateFmt('%Y');s/\b0+\B//g}]"
Oh man! Just when I thought it was safe to go back into the water...
I just noticed when I checked some of my ExifTool outputs, that any example of filenames that would end up as only [Directory name. YEAR], had an extra hidden space before the [
(http://s01.geekpic.net/di-ZPSQB5.png)
Output as seen from ExifMixer:
(http://s01.geekpic.net/di-CZBISY.png)
Windows seems to hide any extra pre-spaces when it shows the result in the columns, yet they are there when you view the results with ExifTool.
What do I need to change now? Do I need to add another ;s/ +/ /g somewhere?
Note all the other examples shown in that attached pic were perfect.
The problem is that with your current command there will always be an additional space, even if the front part is empty (you "hard-coded" that space). We can fix this by slightly modifying your code:
"-XPcomment<${filename; $_ =~ s/^(?:.*\[PIX\d+\]\s*)?((?:(?!modx).)*)(?:\s*modx.*|\....$)/$1/;s/ +/ /g;s/ +$//;s/^(.+)$/$1 /}[${directory; use Cwd 'abs_path';$_ = abs_path($_); $_ =~ s/.*\///; $_ =~ s/^[0-9- ]*//;}. ${DateTimeOriginal;DateFmt('%Y');s/\b0+\B//g}]"
The modification is that I removed the hard-coded space and added it conditionally (only when there was actually some text).
Thanks Hayo, but nope. It's the same result for me as before.
It actually put an extra space for me before the "[" in this case: "test [Tests. 2019]"
That can't be; it works for me. Please copy the command verbatim! Spaces are important ;)
Ok. Let me have a closer look at it. Might be something stupid I'm doing. I'll get back to you soon.
Oops :-[ Yes. I must have done something stupid. It works now!
Thanks :)
Here's a quick & hopefully easy question to answer...
What's the easiest way to output one blank line, or more, (ie. to act as a spacer) between the output for multiple images?
Eg,
I could have:
======== W:/Tests/2019-05-11 12-54-58 IMG_0125 [PIX343107] Santa falling down the chimney modx bla bla bla.JPG
XP Comment : Santa falling down the chimney [Tests. 2018]
Comment : Santa falling down the chimney [Tests. 2018]
======== W:/Tests/2019-05-11 12-54-58 IMG_0125 [PIX343107] Santa falling down the chimney.JPG
XP Comment : Santa falling down the chimney [Tests. 2018]
Comment : Santa falling down the chimney [Tests. 2018]
======== W:/Tests/2019-05-11 12-54-58 IMG_0125 [PIX343107].JPG
XP Comment : [Tests. 2018]
Comment : [Tests. 2018]
look something like this:
======== W:/Tests/2019-05-11 12-54-58 IMG_0125 [PIX343107] Santa falling down the chimney modx bla bla bla.JPG
XP Comment : Santa falling down the chimney [Tests. 2018]
Comment : Santa falling down the chimney [Tests. 2018]
======== W:/Tests/2019-05-11 12-54-58 IMG_0125 [PIX343107] Santa falling down the chimney.JPG
XP Comment : Santa falling down the chimney [Tests. 2018]
Comment : Santa falling down the chimney [Tests. 2018]
======== W:/Tests/2019-05-11 12-54-58 IMG_0125 [PIX343107].JPG
XP Comment : [Tests. 2018]
Comment : [Tests. 2018]
Add -echo "" -echo3 "" -echo3 "" -echo3 "" to your command.
See the -echo option (https://exiftool.org/exiftool_pod.html#echo-NUM-TEXT) for an explanation.
Thanks Phil. I'll take a look.
Ooops. That doesn't do it. Sorry. It only puts the lines at the very start and end.
I think you'll need to use the -p option to do what you want.
- Phil
OK. Thanks again.
I figured it out (using the -p option with $/ for a newline). It took a bit of experimenting, but it finally worked. ;)
I've just realised that there are some nested Windows directories containing "groups" of my photos.
So, I need to be able to add part of the directory name 1 level higher up.
For example, when my folks went on an overseas canal trip to Europe, (because of the large number of pics they took), I stored their photos in a hierarchy of folders, which contains the photos of those days that they were travelling through a certain region.
Here's one cut-down example we can work with:
(Note: I've already stripped out all foreign filename characters, because as expected, that was creating hell with some utilities, and on my Media Players).
W:\Photos\2010-08-08 Jewels of Europe River Cruise\2010-08-13 Rothenburg and Wuerzburg, Germany\
2010-08-12 18-13-10 P1030222 [PIX180903] modx1.jpg
2010-08-13 07-25-22 P1030226 [PIX796859].jpg
2010-08-14 09-51-00 P1030231 [PIX356360] modx2c.jpg
---------------------------------------------------------------------
These filename examples are typical of all those photos in the folders, ie. they will parse as "empty" because there is nothing after the "] " or before modx, so only the directory names will show, but there are some cases where I've added better descriptions to the filenames, (just before the modx), which should get parsed through, as before.
Like in my previous examples, for each photo, I'd like to have the XPComment tag populated with the following:
Rothenburg and Wuerzburg, Germany (Thu. 12 Aug 2010) [Jewels of Europe River Cruise, 2010]
Rothenburg and Wuerzburg, Germany (Fri. 13 Aug 2010) [Jewels of Europe River Cruise, 2010]
Rothenburg and Wuerzburg, Germany (Sat. 14 Aug 2010) [Jewels of Europe River Cruise, 2010]
Note the "Day" ie Thu, Fri, Sat, etc would preferably need to be calculated for each photo.
If that's not possible, don't worry as I can probably do without that, as I'm aware that will "probably" add a lot more complexity(?).
The code to achieve "almost" what I desire (but doesn't yet grab the part of the dir name 1 level higher up, nor day of the week) is:
"-XPcomment<${filename; $_ =~ s/^(?:.*\[PIX\d+\]\s*)?((?:(?!modx).)*)(?:\s*modx.*|\....$)/$1/;s/ +/ /g;s/ +$//;s/^(.+)$/$1 /}${directory; use Cwd 'abs_path';$_ = abs_path($_); $_ =~ s/.*\///; $_ =~ s/^[0-9- ]*//;} (${DateTimeOriginal;DateFmt('%b %d, %Y');s/\b0+\B//g})"
--> This gives: Rothenburg and Wuerzburg, Germany (Aug 12, 2010)
--> but I want: Rothenburg and Wuerzburg, Germany (Thu. Aug 12, 2010) [Jewels of Europe River Cruise, 2010]
The bold bits added please.
Should be easy peasy for you clever guys. ;) Who's up for the challenge? :)
ps. Anyone that yells config file, config file, will get slapped. lol. Nah... Just kidding. I'll kick you instead! ;D I'm fairly sure this will be my final coding so, just one line of code please, if possible. If the calculation of the day of the week adds too much complexity, then and only then, I "might" consider using one. :P Let me know what you think.
Cheers,
-mpegleg Paul
Try this:
"-XPcomment<${filename; $_ =~ s/^(?:.*\[PIX\d+\]\s*)?((?:(?!modx).)*)(?:\s*modx.*|\....$)/$1/;s/ +/ /g;s/ +$//;s/^(.+)$/$1 /}${directory; use Cwd 'abs_path';$_ = abs_path($_); $_ =~ s/.*\///; $_ =~ s/^[0-9- ]*//;} (${DateTimeOriginal;DateFmt('%a. %b %d, %Y');s/\b0+\B//g}) [${directory; $_ = abs_path($_); $_ =~ s#.*/[0-9-]+\s*([^/]+)/[^/]+$#$1#;}]"
This gives me Rothenburg and Wuerzburg, Germany (Wed. Jun 22, 2005) [Jewels of Europe River Cruise] (my test file has a different date than yours).
Bonus points if you fully understand my changes ;)
:o Wow! I am highly impressed Hayo. I just tested it, and your code worked perfectly. I think you deserve the bonus points, not me.
I'll have a look at what you did soon, but forgive me if I have to rush off and have a quick lie down, after studying it.
Cheers,
-Paul
Can't thank you enough for that. I was really expecting I might have been pushing the limits too much with what could be actually be done in a single line of code with ExifTool and Regex. I should never have doubted it!
Thanks, but I'll pass on the bonus points for now Hayo. I had a quick look, but I think learning Mandarin would be easier. :'(
(It's going to take me a while to fully learn & understand the Regex syntax, but I'll certainly do that one day).
So, here's another one I'll throw at you while you're on fire!
You'll see that I've added a "-" separator between the Current Directory and the Date, so that:
W:\Photos\2010-08-08 Jewels of Europe River Cruise\2010-08-08 Amsterdam, Netherlands\
2010-08-08 21-12-43 P1030160 [PIX506764] In transit at Singapore Changi Airport.jpg
becomes:
In transit at Singapore Changi Airport - Amsterdam, Netherlands (Sun. Aug 8, 2010) [Jewels of Europe River Cruise]
It's obviously an if/then conditional case, because if the parsed filename ends up being empty, then obviously I won't want the " - " showing in the result like for:
W:\Photos\2010-08-08 Jewels of Europe River Cruise\2010-08-13 Rothenburg and Wuerzburg, Germany\
2010-08-13 07-25-22 P1030226 [PIX796859].jpg
Rothenburg and Wuerzburg, Germany (Fri. 13 Aug 2010) [Jewels of Europe River Cruise, 2010]
^-- No " - " at the start, which is correct for this particular filename.
"-XPcomment<${filename; $_ =~ s/^(?:.*\[PIX\d+\]\s*)?((?:(?!modx).)*)(?:\s*modx.*|\....$)/$1/;s/ +/ /g;s/ +$//;s/^(.+)$/$1 /} - ${directory; use Cwd 'abs_path';$_ = abs_path($_); $_ =~ s/.*\///; $_ =~ s/^[0-9- ]*//;} (${DateTimeOriginal;DateFmt('%a. %b %d, %Y');s/\b0+\B//g}) [${directory; $_ = abs_path($_); $_ =~ s#.*/[0-9-]+\s*([^/]+)/[^/]+$#$1#;}]"
---> So,... is it easy to add a conditional case to this, (on 1 line also)?? Pretty please. Make it so :)
Obviously I'll need to learn the if/then syntax (or however you do it in Regex) because it would be very good in cases like this, where it would probably make better sense to just name that particular photo as:
"In transit at Singapore Changi Airport..." without the Amsterdam, Netherlands part, as we haven't arrived in The Netherlands yet. If we had... I'd be sure to say... G'day Mate, and Thanks! ;)
ps. I can imagine getting very fancy so that I could base the conditionality ("is that even a word? The spellchecker says no") on various flag characters in the filename, (or perhaps even a metadata tag) as to what would finally be output... but, I'm getting ahead of myself, and that can wait for another... lifetime. Baby steps Paul, baby steps first!
EDIT(s):
I can't believe whoever wrote those Regex instructions (https://www.regular-expressions.info/conditional.html) truly expect any n00bs to make sense of that page. I got a headache just quickly browsing it. eek!
Now Googling... "Regex for Dumb & Dumber Dummies" (https://medium.com/factory-mind/regex-tutorial-a-simple-cheatsheet-by-examples-649dc1c3f285)... here I come ;D
Oh. regular expressions 101 (https://regex101.com/)... I have a sneaky feeling you guys have been giving that site a workout. 8)
That's such a cool site for learning and testing out Regex. Nice. (EDIT: Well it will be once I figure out how to drive the thing).
Also, RegExr (https://regexr.com/) is excellent as well, but I guess these are regular tools you guys all use anyway?
I'm also learning a lot from this YouTube video. (https://www.youtube.com/watch?v=lAmwLbtjuHY) It has some great Regex info for any other n00bs like me that might come across this post one day.
...and don't worry, I know we're starting to stray into the territory of pure Regex, rather than discussion and help surrounding ExifTool, so I'll try not to ask for too many Regex type questions from now on. Promise I will try.
ExifTool + Regex = Awesomeness!
Hi all.
I've been experimenting with the "-if" operator, (Powerful! :D ) but I need a little help please with how I'd place it in the correct position in the string.
This entire code gets executed and works (or at least does what I currently want):
"-XPcomment<${filename; $_ =~ s/^(?:.*\[PIX\d+\]\s*)?((?:(?!modx).)*)(?:\s*modx.*|\....$)/$1/;s/ +/ /g;s/ +$//;s/^(.+)$/$1 /} - ${directory; use Cwd 'abs_path';$_ = abs_path($_); $_ =~ s/.*\///; $_ =~ s/^[0-9- ]*//;} (${DateTimeOriginal;DateFmt('%a. %b %d, %Y');s/\b0+\B//g}) [${directory; $_ = abs_path($_); $_ =~ s#.*/[0-9-]+\s*([^/]+)/[^/]+$#$1#;}]" -if "$comment eq "1""
based on whether comment="1"
...but, I only want the " - " to be added to the string if that condition is met. Any ideas how I'd structure the whole line to achieve that?
The " - " that I want to conditionally appear, can be seen in the code here: ...} - ${directory; use Cwd...
The conditional "-if" at the moment is at the very end, which is obviously not where I want it.
Thanks,
-Paul
ps, Don't worry too much about the particular metadata tags I'm using (eg. comment + XPComment)... they are just for this example only, for simplicity. I'll be using more robust ones in reality.
The location of the -if option (https://exiftool.org/exiftool_pod.html#if-NUM-EXPR) can be anywhere in the command as long as it doesn't interfere with previous parts of the command. For example, if you were using the -o (outfile) option (https://exiftool.org/exiftool_pod.html#o-OUTFILE-or-FMT--out), you couldn't place it between the -o and the secondary parameter of that command.
An exiftool command isn't like an IF statement in a programming language. It affects the whole command, not just the stuff that comes after it. If the -if returns false, no part of that command will be executed. Exception: See the -execute option (https://exiftool.org/exiftool_pod.html#execute-NUM). Exception to the exception: See the -Common_Args option (https://exiftool.org/exiftool_pod.html#common_args).
Paul,
I don't understand your -if (what's it for?) but to only have the " - " if there's really something following it, is easy:
"-XPcomment<${filename; $_ =~ s/^(?:.*\[PIX\d+\]\s*)?((?:(?!modx).)*)(?:\s*modx.*|\....$)/$1/;s/ +/ /g;s/ +$//;s/^(.+)$/$1 /}${directory; use Cwd 'abs_path'; $_ = abs_path($_); $_ =~ s/.*\///; $_ =~ s/^[0-9- ]*//; $_ =~ s/^(.+)$/ - $1/;} (${DateTimeOriginal;DateFmt('%a. %b %d, %Y');s/\b0+\B//g}) [${directory; $_ = abs_path($_); $_ =~ s#.*/[0-9-]+\s*([^/]+)/[^/]+$#$1#;}]"
I removed the fixed part " - " and added it conditionally by using $_ =~ s/^(.+)$/ - $1/; inside the part that makes up the second part.
Hi Hayo. Thanks for helping. I really appreciate it.
Dont worry, It's hard to explain these things sometimes, and this is starting to get a little bit complex, as I move ahead with my "scenarios". ;).
I'm not quite sure what you did then, but I don't think I notice any difference in the output.
(Note: The directories, photos, and metadata tags used in the following example are all chosen simply for testing purposes).
Here's a pic that might help me explain the current problem better:
(http://s01.geekpic.net/di-5716F1.png)
Note the "-". I don't want that to appear when the filename parses as an "empty" string.
Now, provided I can get that pesky dash to disappear,... this all got me thinking further (perhaps way too far ahead)...
What if I could control what was to be output, based on what was contained in:
Scenario a). In a metadata tag. Such as the "0" or "1" that you'll see in my Subject column (XPSubject)
=or=
Scenario b). A Filename contained a certain key character string such as for example..."-flag1-"
I could then setup my files, so that they'd automatically be renamed as I want, based on whether a). XPsubject="1"
=or=
b). The filename contains "-flag1-".
Do you see what I'm getting at? That would be very powerful, because it would be global for my entire photo collection, if I setup one of those flag situations correctly. That way, I wouldn't have to worry about what the Directory structure was, or how the filenames were constructed.
The file renaming would be performed based independently on what the Directories and/or filenames were,
BUT I'd also be able to have exceptions when it struck those filename Flags.
Note: I'd only use one or the other of those scenario methods, but I haven't decided which one yet, as I'm still mulling over these ideas, to ascertain what might work best.
I "think" this is where I need to take advantage of the -if" conditional operator.
I've just decided I'm going to mull over this for a little bit longer, as I'm obviously still a bit muddled in my thinking about the Regex vs "-if" scenarios. Leave that with me for now. :)
Cheers
-Paul
ps. That damned "-" still has to disappear though. That's priority #1 ;D
Ah, the front part was what could be empty, I thought it was the second part...
Try this:
"-XPcomment<${filename; $_ =~ s/^(?:.*\[PIX\d+\]\s*)?((?:(?!modx).)*)(?:\s*modx.*|\....$)/$1/;s/ +/ /g;s/ +$//;s/^(.+)$/$1 - /}${directory; use Cwd 'abs_path'; $_ = abs_path($_); $_ =~ s/.*\///; $_ =~ s/^[0-9- ]*//;} (${DateTimeOriginal;DateFmt('%a. %b %d, %Y');s/\b0+\B//g}) [${directory; $_ = abs_path($_); $_ =~ s#.*/[0-9-]+\s*([^/]+)/[^/]+$#$1#;}]"
Thanks Hayo. Don't give yaself a headache over it, but I really do appreciate your help.
Ok. Now that I think I've de-scrambled my brain... I remember why I thought we'd have to use the "-if" condition.
SCENARIO:
Only "some" of my Directories have this "Main Directory/Sub Directory" structure for a particular group of photos ... mostly Vacation Photos. eg. 2010-05-01 Russian Vacation/2010-05-01 Moscow/*.jpg
These however are the exception. Most are just separate Directories of random daily event photos all in date order through the years. Eg).
Directories...
2001-10-05 Pictures of our lovely cute little kitten
2004-08-14 More pictures of the stupid cat
2015-07-08 Even more pictures of the now decrepit old flea-infested moggy
2017-01-01 Fluffy's garden burial service - sad
So, jokes aside... I don't "always" want the higher Directory name to be included in the output tag. In fact for most of the Directories, I won't want it.
Now, I don't expect, and I'd rather you didn't help me with the intricacies of setting up the syntax to handle that, but I would like some advice on whether you think I should be able to do that with standard ExifTool + Regex, as we've been doing so far, or would I need to get fancier and use the "-if" Conditional structure.
This is where I was thinking I could use a metadata "flag" (ie. Tag value="1") to trigger the condition.
Then, I'd only have to set those particular Vacation photo groups with that respective tag set=1, and everything would be automatic.
How complex would this be to achieve?
Aha. You edited your post with the corrected code! Yay. Thank you. I've been "hanging out" waiting for it, because I couldn't seem to work it out myself, but I've just tested it and it seems to work fine now. :)
Lucky I saw your modified post though, Hayo. ;) That's a somewhat "risky" way of posting, because I don't get any notification of any change. I usually have my browser set to alert me of any new posts, but it won't of course alert me of modified posts.
It was pure luck that I noticed that what you had written looked different from before... ie. You'd removed the "I don't understand part". Anyway, just a friendly tip there, because I was really looking forward to the modified code, even though I was trying to stay polite and calm. lol. Now I can really start do some serious work with my photo collection organising.
Thanks again Hayo,
and I much, much appreciate all your efforts in helping me with that code!
-Paul
EDIT: Sorry. I may have just missed seeing your previous post. Glad I did though! As I said... It' s working really well. now,
Hayo, I just tested your new and improved super-code, and I can confirm,
that out of a thousand or so of my pics, so far there were no surprises. Worked like a dream. :D
You're a legend. It will save me so much time like you won't believe!
Thanks again, (I sure seem to be doing a lot of thanking lately, but I really am happy)
-Paul
Hi.
As this has huge practical application value for me, I'm just experimenting a little with the -if conditional option, with multiple commands on the one line.
Following is a very basic example, just to simplify what I'm trying to achieve with the -if option.
It's a typical "if" "then" "else" situation, but because there is no "else" operator, I'm a bit unsure how to construct it.
Here I'm using the value contained in XPSubject as a kind of "flag". It will contain either the exact value of "1" =or= "something" else, (which would be unknown and irrelevant).
-if $XPSubject eq "1" -p $directory
-if not $XPSubject eq "1" -p $filename
Obviously the commands will be much more complex in actuality,
but I'd like to put these commands on the same line. Obviously the -if option applies to the whole line, so I'm "guessing" I have to use the -execute option somehow. I tried putting that after my first line above, followed by the second "-if" statement, but that didn't work.
How would I construct the full command, to enable both "-if"s to occur one after the other, on just one line? Is that possible, or does it absolutely require 2 separate exiftool.exe command statements?
Also, I was just thinking some more (dangerous I know!) about extending this idea, with more "flag" values, thus:
-if not $XPSubject eq "1" -p $filename <-- so most of the time it will do this operation
-if $XPSubject eq "1" -p $directory
-if $XPSubject eq "2" -DateTimeOriginal
Once again, how would I run it all on one line? Note: To keep things simple, the execution sequence would not be important here.
EDIT: I guess I could write a simple batch file to accomplish the same thing, but It still leaves me wondering if it's possible to put them all on one ExifTool command line :-\
exiftool -if "$XPSubject eq '1' " -p $directory -execute -if "not $XPSubject eq '1' " -p $filename -common_args /path/to/working/directory
Assuming that you're processing the same directory, you have to put the directory path at the end after the -Common_Args option (https://exiftool.org/exiftool_pod.html#common_args). You also want to put anything else that would be in common to both commands at this point, such as -r.
Any thing before the -execute is combined with the -common_args options and the command is run. The it starts the second part, combines with the common args again, and since there isn't anything left, it runs all that and exits.
Thanks very much StarGeek.
I'll have a good thorough look at that, and have some fun playing around with it soon.
Cheers,
Paul
OK. I got it working so well now, using about 5 sequential commands. That's just what I'd hoped all along to be able to do, as it opens up a whole new realm of completely automating all my file and metadata tag renaming. Brilliant :D
Once again... many thanks to StarGeek, Hayo & Phil.
Cheers,
-Paul
ps. It was a long, and difficult journey (probably more so for you folks putting up with all my "science-project-homework-type" questions... but I got there in the end). As they say... All's well that ends well. :)
I know you are "supposed" to use a format file to better achieve the formatted text output, which I have been doing, but I was just wondering (as I always do - If ya don't ask, you'll never know)...
eg). In the following test scenario (with XPSubject="1") everything will output on it's own new line:
-m -p "XPSubject: " -p $XPSubject -p " Creation Date: " -p $DateTimeOriginal FILE
XPSubject:
1
Creation Date:
2019:06:11 14:04:20
I'd prefer:
XPSubject: 1 Creation Date: 2010:08:14 09:51:00
Is it possible to suppress the CR/LR after each -p option?
If not, then yes, I'll stick with the format file, but it would be useful for the occasional quick and dirty little runs where I didn't want to have to bother.
I guess what I was hoping for, is another "switch" option that tells the -p option not to CR/LF after the next output ends.
Could it be the -w option I'm looking for? I'm not really familiar with that yet. I only want console output though.
Just bring everything you want printed into one string:
-m -p "XPSubject: $XPSubject Creation Date: $DateTimeOriginal"
Oh Hayo. Now that was just too darn simple. Laughing at myself.
Thank you!!!!
Sometimes the complete obvious is staring one in the face!
Help please! My Regex knowledge is unfortunately still too basic for this...
I'd like a simple Regex expression to match the 1st, 2nd, 3rd, 4th, or 5th Character in a 5-character string. Let's call it Code5. eg. PC101
This is so that I can do an "-if" option condition on it, to then perform an ExifTool command.
ie. I was thinking of having a 5-character alphanumeric code that would allow the inspection of a particular character in the 5-character string (that will be stored in a specific metadata tag), to determine whether to perform a specific ExifTool command, or not.
eg,
Something along the lines of:
-if "1st character of the Code5 eq 'P' " ...do this ExifTool command... Perhaps output the Parent Directory name
-if "2nd character of the Code5 eq 'C' " ...do this ExifTool command... Perhaps output the Current Directory name
The part I need is the Regex that can obtain the specific alphanumeric character, based on it's position in the string ie. "Character x of the Code5"
Hopefully that makes sense. If not, let me know, and I'll try to explain it better.
Many Thanks,
-Paul
This can be done with a regex:
-if "$code5 =~ /^P/"
-if "$code5 =~ /^.C/"
or without a regex:
-if "substr($code5,0,1) eq 'P'"
-if "substr($code5,1,1) eq 'C'"
(Assuming the tag name is "Code5")
Fantastic. That was quick!
Thanks Phil.
I'll give it a whirl, and see what works best. :)
Phil, I searched for some info on the correct usage syntax for the "substr" operator, but couldn't find it.
Would you mind please pointing me in the right direction for it?
Much appreciated,
-Paul
https://perldoc.perl.org/functions/substr.html
Thank you. I can see... in the future... I'm going to have to learn Perl. ;)
It looks like it would certainly be helpful in getting the most out of ExifTool.
This is no biggie at all, but when I use the "-if" option, I get the standard console notifications when the condition fails.
eg).
"138 files failed condition"
Now that's all fine and good, because everything is working as it should, but I'd prefer to not even see those messages at all, and just have these messages:
"138 image files updated"
Is it possible to suppress them somehow, or do I just need to suck it up, be a man, and ignore them? ;)
You can use -q to suppress all the messages, but there is no option to suppress just some of them.
- Phil
Ah ok. I thought that might be the case. No worries.
After all the incredible help you good people at ExifTool Forum have provided me, I thought it's only fair that I showed you the end result. Two weeks ago, I'd never heard of ExifTool. (I know... shame on me :-[)
Nor did I really know much about metadata. In two weeks, even though I still can't understand much of the gobbledegook of the commands (esp. Regex!), I feel that I have achieved more than I could possibly have hoped for, with the automation of my file and tag renaming requirements.
Here's a short real-time demo video I just created (Using ExifMixer (http://www.moonsoftware.com/exifmixer.asp) running ExifTool) of what I have achieved so far. Feel free to offer any further advice, code changes, etc.
Note that ExifMixer allows the use of multiple lines for the various options, which makes it far easier to read the command line syntax.
https://www.youtube.com/watch?v=4UsanggFUBk
(http://s01.geekpic.net/di-W0Y08S.jpeg) (https://www.youtube.com/watch?v=4UsanggFUBk)
The specific tag output names are all created based on the contents of the Windows "Copyright" tag info. I know that's not ideal, but I needed a tag whose properties were very easily changeable and visible in Windows Explorer's columns. I personally don't normally make use of the Copyright tag, because obviously my photos are just personal family snaps, and I have no other need for it. Even if it gets clobbered by other editing programs, it would be no big deal, and I could always recover and copy it back from another duplicated tag, that might be a bit more robust and unused.
The H represents files that are "Hidden". Unfortunately as you'll see (and has been discussed here) any writing operation performed by ExifTool will "Unhide" the file status. I hide all my original images (that have a corresponding unhidden edited file) in the same folder. This works for me. I found a workaround whereby using the Copyright tag to hold the letter "H" would represent which files needed to be re-hidden after using ExifTool. After any ExifTool writing operation, I thus would search for my *.jpg files in Explorer, re-order them in Alphabetical order based on the Copyright column, select all those, and then do a bulk Hidden-file attribute properties change, based on the info contained in the Copyright tag for those applicable files.
Too easy.
Regards,
and many thanks,
Paul :)
Quote from: mpegleg on June 22, 2019, 02:15:56 AM(esp. Regex!)
When you decide to try and figure regex out more, try copying the expression into a website like Regex101 (http://regex101.com). It will give you a step by step break down of the expression in the upper right corner and it will highlight sections of the regex and tell you what each part does as you hover over it.
QuoteThe specific tag output names are all created based on the contents of the Windows "Copyright" tag info. I know that's not ideal, but I needed a tag whose properties were very easily changeable and visible in Windows Explorer's columns.
...
Even if it gets clobbered by other editing programs,
Copyright is pretty safe. Almost any tag in the XMP, IPTC, or EXIF group is unlikely to get destroyed or overwritten by most programs, unless you specifically tell to. The jpeg
Comment tag and a few other very obscure/rare tags are not necessarily safe.
Happy it all worked out for you.
Thank you StarGeek.
Yes I discovered Regex101 the other day, along with RegExr (https://regexr.com/). They will be very useful.
The only reason I need to use the jpeg comment tag is because the program I use to do the photo resizing and captioning FastStone Photo Resizer (https://www.faststone.org/FSResizerDetail.htm) (which is perfect for doing the resizing), "only" allows a few very specific tags to contain the captions, as you can see in my attached image. Most are for the camera metadata, like Exposure settings etc, which although useful, doesn't really allow me to display my textual descriptive data like Title, Subject, and other comments.
(http://s01.geekpic.net/dt-1QMRIX.png) (http://geekpic.net/pm-1QMRIX.html)
I've tried to get in touch with the author, to suggest he expand the amount of tags one can use, but have so far been unsuccessful in getting any response back. :-\
If he was to use ExifTool in his program, (which I don't "think" he does), of course one would then have access to almost unlimited metadata tags.
Phil, (totally off-topic here, but...)
I notice a little bit further down the page [here] (https://exiftool.org/faq.html#Q21) you say:
[Unfortunately the Windows cmd shell provides no method to get a newline (CR/LF in Windows) into the command line. A linefeed (LF) may be inserted with CTRL-T, but I have found no way to insert a carriage return (CR).]
Excuse my ignorance as I'm not 100% sure that this is what you were trying to achieve here, but I thought I'd mention it just in case you weren't aware of it, as it might be important...
If you place a " ^" after the options on each line it allows you to place them on separate lines in the Windows command console.
Eg:
exiftool ^
-m ^
-overwrite_original ^
-comment="123" ^
image.jpg
executes the complete command as though it was entered on one line.
For example, the above code (and importantly including the "blank line" after image.jpg) can all be copied and pasted, and it will immediately execute upon pasting into the Console.
With the mouse, you must "click & drag upwards" from below image.jpg to allow the capture of the hidden CR/LF characters, when copying the text. (You can also mouse downwards, as long as you mouse drag below image.jpg).
Note: The space is very important before each ^ character.
So, the ^ with a blank line included after, should be the equivalent of a CR/LF.
Possibly this is only the LF that you were talking about, rather than the CR, but it doesn't do any harm to mention it just in case.
Unless I am mistaken, this still doesn't insert a CR (or LF) into the arguments. It only allows you to spread your command over multiple lines. When ultimately the command receives the arguments, these multiple lines are replaced by a single line (the line endings are basically just a space). On Linux/Mac this is done by ending the line with a \.
Yeah. I think you are right. I just thought I'd mention it, "just in case", because I came across it, and had never personally seen it mentioned before. :)
Hi. I hope someone can please help with the Regex code on this one.
Using the following code:
"-XPComment<${filename; $_ =~ s/^(?:.*\[PIX\d+\]\s*)?((?:(?!modx).)*)(?:\s*modx.*|\....$)/$1/;s/ +/ /g;s/ +$//} (${DateTimeOriginal;DateFmt('%a. %b %d, %Y');s/\b0+\B//g}) [${directory; $_ = abs_path($_); $_ =~ s#.*/[0-9-]+\s*([^/]+)/[^/]+$#$1#;}]"
and this Windows file:
W:\Photos\2010\2010-08-08 Jewels of Europe River Cruise\2010-08-08 Amsterdam, Netherlands\
2010-08-08 21-12-43 P1030160 [PIX506764] In transit at Singapore Changi Airport.jpg
I'm getting the result with the XPComment tag as:
Waiting for flight from Singapore Changi Airport (Sun. Aug 8, 2010) [W:/Photos/2010/2010-08-08 Jewels of Europe River Cruise/2010-08-08 Amsterdam, Netherlands]
yet, what I'd like is:
Waiting for flight from Singapore Changi Airport (Sun. Aug 8, 2010) [Jewels of Europe River Cruise]
I'm still not quite sure what small modification I need to make in the last bit of the code, to achieve this.
ie. I'd like the Parent Directory name included (without the date), but I don't want the Current Directory name included, which is what I "was" requesting previously.
Note: the Parent Directory could appear anywhere eg: W:/Test/1/Photos/123/2010-08-08 Jewels of Europe River Cruise/2010-08-08 Amsterdam, Netherlands
but you can always assume that both the Parent and Current Directory Names will always be: "yyyy-mm-dd xxxxxx"
Many thanks,
-Paul
Ps. The biggest problem I'm having with trying to decipher the Regex code, is that it is, of course, a variant of the Perl Programming language, thus I can't just enter it into regex101.com and expect it to work. Very tricky, but I am trying to learn it. :-\
EDIT: OK. I got this far using regex101
... so much to learn! :-\
Ideally I guess I want to search backwards from the last "/" until I hit the "-dd" or "-mm-dd".
So searching backwards for "-??-??" is probably more feasible. I don't know. ie. (?<=[-]......)([^\/]+)
This is getting close... (testing with digits before the "Jewels...").
(http://s01.geekpic.net/di-JMMSLI.png)
Hi Paul,
I don't understand the result you are getting at all; the last regexp $_ =~ s#.*/[0-9-]+\s*([^/]+)/[^/]+$#$1#;
should already deliver the result you're after:
perl -E '$x ="W:/Photos/2010/2010-08-08 Jewels of Europe River Cruise/2010-08-08 Amsterdam, Netherlands"; say qq{Before=$x}; $x =~ s#.*/[0-9-]+\s*([^/]+)/[^/]+$#$1#; say qq{After=$x}'
Before=W:/Photos/2010/2010-08-08 Jewels of Europe River Cruise/2010-08-08 Amsterdam, Netherlands
After=Jewels of Europe River Cruise
(to test this on windows, swap the single and double quotes).
Thanks Hayo.
Indeed, I believe also that it should have worked, as the more complex command does, but...
I also tried it on my D: drive, which is not a network drive. Using the Windows command console, I got the exact same result:
exiftool "-XPcomment<[${directory; $_ = abs_path($_); $_ =~ s#.*/[0-9-]+\s*([^/]+)/[^/]+$#$1#;}]" "2010-08-08 23-11-28 IMG_5479 [PIX610424] Waiting for flight from Singapore Changi Airport.jpg"
D:\Photos\2010\2010-08-08 Jewels of Europe River Cruise\2010-08-08 Amsterdam, Netherlands>exiftool "-XPcomment<[${directory; $_ = abs_path($_); $_ =~ s#.*/[0-9-]+\s*([^/]+)/[^/]+$#$1#;}]" "2010-08-08 23-11-28 IMG_5479 [PIX610424] Waiting for flight from Singapore Changi Airport.jpg"
Warning: Undefined subroutine Image::ExifTool::abs_path called for 'directory' - 2010-08-08 23-11-28 IMG_5479 [PIX610424] Waiting for flight from Singapore Changi Airport.jpg
1 image files updated
Note the: "Warning: Undefined subroutine..."
This ends up with:
XPComment=[.]
Note that I "should" have tested it on the command line previously, but I was actually using ExifMixer. ExifMixer gives the result (with no errors) of the whole of the path:
XPComment=[D:/Photos/2010/2010-08-08 Jewels of Europe River Cruise/2010-08-08 Amsterdam, Netherlands]
Strange thing is, the previous full (more complex) command (using either the command console, or within ExifMixer) works perfectly:
exiftool "-XPcomment<${filename; $_ =~ s/^(?:.*\[PIX\d+\]\s*)?((?:(?!modx).)*)(?:\s*modx.*|\....$)/$1/;s/ +/ /g;s/ +$//;s/^(.+)$/$1 - /}${directory; use Cwd 'abs_path'; $_ = abs_path($_); $_ =~ s/.*\///; $_ =~ s/^[0-9- ]*//;} (${DateTimeOriginal;DateFmt('%a. %b %d, %Y');s/\b0+\B//g}) [${directory; $_ = abs_path($_); $_ =~ s#.*/[0-9-]+\s*([^/]+)/[^/]+$#$1#;}]" "2010-08-08 23-11-28 IMG_5479 [PIX610424] Waiting for flight from Singapore Changi Airport.jpg"
D:\Photos\2010\2010-08-08 Jewels of Europe River Cruise\2010-08-08 Amsterdam, Netherlands>exiftool "-XPcomment<${filename; $_ =~ s/^(?:.*\[PIX\d+\]\s*)?((?:(?!modx).)*)(?:\s*modx.*|\....$)/$1/;s/ +/ /g;s/ +$//;s/^(.+)$/$1 - /}${directory; use Cwd 'abs_path'; $_ = abs_path($_); $_ =~ s/.*\///; $_ =~ s/^[0-9- ]*//;} (${DateTimeOriginal;DateFmt('%a. %b %d, %Y');s/\b0+\B//g}) [${directory; $_ = abs_path($_); $_ =~ s#.*/[0-9-]+\s*([^/]+)/[^/]+$#$1#;}]" "2010-08-08 23-11-28 IMG_5479 [PIX610424] Waiting for flight from Singapore Changi Airport.jpg"
1 image files updated
I end up with:
XPComment=Waiting for flight from Singapore Changi Airport - Amsterdam, Netherlands (Sun. Aug 8, 2010) [Jewels of Europe River Cruise]
Change the first command into exiftool "-XPcomment<[${directory; use Cwd 'abs_path'; $_ = abs_path($_); $_ =~ s#.*/[0-9-]+\s*([^/]+)/[^/]+$#$1#;}]" "2010-08-08 23-11-28 IMG_5479 [PIX610424] Waiting for flight from Singapore Changi Airport.jpg"
(i.e. add use Cwd 'abs_path';).
Sir. You are Legend! ;D
Hello.
Long time no see. :) I hope you are all well since I last visited.
Unfortunately I'm a bit rusty in the ol' Regex department. :-\
I was wondering if someone could please advise me of the modification to this code, to achieve the following:
An example Windows filename: 1963-09-01 [1965-08 S#01] [PIX945034] test1.jpg
This code:
-comment<${filename;m/(\[(.+?)\])/;$_=$1}
will result in the comment tag containing [1965-08 S#01]
I would like to only have everything between the first square brackets like so... 1965-08 S#01
ie. with no square brackets included in the result.
Cheers,
-Paul :)
Try this
-comment<${filename;m/\[([^]]+)\]/;$_=$1}
The breakdown
Match the first bracket \[
Start a capture group (
Start a character set [
Negate the this character set, in other words, match any character not in this set ^
Close bracket character as part of the set (may or may not need a backslash escape) ] or maybe \]
Close bracket which closes the character set ]
Match one or more of the previous character, which was any character that is not a close bracket +
Close the capture group )
The final matching bracket isn't necessary, but it can be left in if it's easier to read that way.
Example on Regex101 (https://regex101.com/r/vISySV/1)
Thanks StarGeek. That did the trick. :)
.. and thanks also for the excellent breakdown!
... and if I wanted to substitute the # for a SPACE character?
ie. 1965-08 S#01
becomes: 1965-08 S 01
Quote from: StarGeek on January 30, 2020, 12:26:06 AM
Close bracket character as part of the set (may or may not need a backslash escape) ] or maybe \]
I would definitely use
\] here. But if it works without the
\, then I have learned something.
- Phil
Quote from: mpegleg on January 30, 2020, 12:54:52 AM
... and if I wanted to substitute the # for a SPACE character?
Try this:
-comment<${filename;m/\[([^\]]+)\]/;$_=$1;tr/#/ /}- Phil
Quote from: Phil Harvey on January 30, 2020, 07:14:58 AM
I would definitely use \] here. But if it works without the \, then I have learned something.
- Phil
Yes, I just tried it both ways, and it
does work with or without the \ escape.
Quote from: Phil Harvey on January 30, 2020, 07:16:42 AM
Try this:
-comment<${filename;m/\[([^\]]+)\]/;$_=$1;tr/#/ /}
- Phil
Thanks Phil. Perfect :)
... and finally, while I'm on it... what if I wanted to remove the # so that:
ie. 1965-08 S#01
becomes: 1965-08 S01 <-- ie. the # just gets removed with no space nor character substitution.
tr/#//d instead of tr/#/ /
Excellent. Many Thanks.
Quote from: Phil Harvey on January 30, 2020, 07:14:58 AM
I would definitely use \] here. But if it works without the \, then I have learned something.
Yeah, I would tend to add the escape as well but it didn't make it into my notes when I was first researching what characters needed escaping. I wasn't sure if it might have been dependent upon the language involved or not. It's not a character I use outside of it's regex usage.
From the Perl documentation:
A ] is normally either the end of a POSIX character class (see POSIX Character Classes below), or it signals the end of the bracketed character class. If you want to include a ] in the set of characters, you must generally escape it.
However, if the ] is the first (or the second if the first character is a caret) character of a bracketed character class, it does not denote the end of the class (as you cannot have an empty class) and is considered part of the set of characters that can be matched without escaping.
Learn something new every day. :)
- Phil