Printing a tag's information in alphabetical order?

Started by rodertroy, March 06, 2021, 02:02:29 PM

Previous topic - Next topic

rodertroy

I have many jpegs with information in the Artist tag. There are multiple images with the same information in the Artist tag. When I run the following command:

exiftool -s -Artist *.jpg

I get the following output:

Artist                          : pinetree
======== ffff979.jpg
Artist                          : pinetree
======== ffff980.jpg
Artist                          : oaktree
======== t45hd97.jpg
Artist                          : oaktree
======== t45hd98.jpg
Artist                          : oaktree
======== t45hd99.jpg

The order of the output is dictated based on the filename, and not the Artist tag info.

I'd like just the Artist tag information to be printed and not the filename, "Artist", the colon, and the equal signs.

I don't want identical Artist tag information printed, but just one instance, like so:

oaktree
pinetree

And I would like the output to be organized alphabetically according to the Artist tag information.

It would also be great if the number of instances of each Artist tag name could be printed alongside the Artist tag information.

So that ultimately the only information I would see would be the following:

oaktree (134)
pinetree (762)

StarGeek

Quote from: rodertroy on March 06, 2021, 02:02:29 PM
I'd like just the Artist tag information to be printed and not the filename, "Artist", the colon, and the equal signs.

You can set the output how you want with the -p (-printFormat) option.  For example
-p "Artist : $Artist"

QuoteI don't want identical Artist tag information printed, but just one instance, like so:

For that, I believe you'll have to use a second program.  On Linux/Mac, you could pipe the output through uniq
exiftool -p "Artist : $Artist" /path/to/files/ | uniq

On Windows, you'll either have to download a port of uniq (see here for example) or use a PowerShell snipped (see this SuperUser question).

QuoteAnd I would like the output to be organized alphabetically according to the Artist tag information.

Use the -FileOrder option, e.g. -Fileorder Artist

QuoteIt would also be great if the number of instances of each Artist tag name could be printed alongside the Artist tag information.

I can't see an easy way to do that without some scripting.  Or if you're comfortable with a spreadsheet program, just export the whole thing as a -csv file and you can manipulate the data as you need.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

Phil Harvey

ExifTool wasn't really meant to do this, but here is a rather command that should do what you want:

exiftool -if '$$Image::ExifTool::MyArtist{$artist} = ($$Image::ExifTool::MyArtist{$artist} || 0) + 1 if $artist; return 0 unless $$self{FILENAME} eq "end"; my @a=map "$$_ ($$Image::ExifTool::MyArtist{$$_})\n", sort keys %Image::ExifTool::MyArtist;print @a' DIR end

Where DIR is the name of the directory containing the images, and you must create a file named "end" in the working directory to act as a stopper for the printout.

The quoting above is for Mac/Linux.  For Windows it would look like this:

exiftool -if "$$Image::ExifTool::MyArtist{$artist} = ($$Image::ExifTool::MyArtist{$artist} || 0) + 1 if $artist; return 0 unless $$self{FILENAME} eq 'end'; my @a=map qq[$$_ ($$Image::ExifTool::MyArtist{$$_})\n], sort keys %Image::ExifTool::MyArtist;print @a" DIR end

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

Hubert

On Mac (and presumably Linux), uniq requires sorted input.

So something like

exiftool -p 'Artist: ${Artist}' /path/to/files/ | sort |uniq

returns

    1 directories scanned
   16 image files read
Artist: Fred
Artist: Jed
Artist: Ned


But if you pipe the output from exiftool straight to uniq:

exiftool -p 'Artist: ${Artist}' /path/to/files/  | uniq

you get

1 directories scanned
   16 image files read
Artist: Ned
Artist: Jed
Artist: Fred
Artist: Ned
Artist: Fred
Artist: Jed
Artist: Fred
Artist: Jed
Artist: Ned
Artist: Jed
Artist: Fred
Artist: Ned
Artist: Jed


Hope this helps,

Hubert



edit (again)

exiftool -p 'Artist: ${Artist}' /path/to/files  | sort  | uniq -c

seems to do the trick

1 directories scanned
   16 image files read
   4 Artist: Fred
   8 Artist: Jed
   4 Artist: Ned

StarGeek

* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).


rodertroy

Quote from: Phil Harvey on March 06, 2021, 06:20:56 PM
ExifTool wasn't really meant to do this, but here is a rather command that should do what you want:

exiftool -if '$$Image::ExifTool::MyArtist{$artist} = ($$Image::ExifTool::MyArtist{$artist} || 0) + 1 if $artist; return 0 unless $$self{FILENAME} eq "end"; my @a=map "$$_ ($$Image::ExifTool::MyArtist{$$_})\n", sort keys %Image::ExifTool::MyArtist;print @a' DIR end

Where DIR is the name of the directory containing the images, and you must create a file named "end" in the working directory to act as a stopper for the printout.

The quoting above is for Mac/Linux.  For Windows it would look like this:

exiftool -if "$$Image::ExifTool::MyArtist{$artist} = ($$Image::ExifTool::MyArtist{$artist} || 0) + 1 if $artist; return 0 unless $$self{FILENAME} eq 'end'; my @a=map qq[$$_ ($$Image::ExifTool::MyArtist{$$_})\n], sort keys %Image::ExifTool::MyArtist;print @a" DIR end

- Phil

I use Linux with WSL.

I get a failed condition error:

Quote(failed condition)
Condition: Global symbol "%self" requires explicit package name (did you forget to declare "my %self"?)

StarGeek

Quote from: rodertroy on March 09, 2021, 08:15:07 AM
I use Linux with WSL.

I get a failed condition error:

Which command did you use? 

I would assume that the first version would be the one to run but I can't test it out because I still haven't figured out how to get the subsystem to work.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

rodertroy

Quote from: StarGeek on March 09, 2021, 10:27:51 AM
Quote from: rodertroy on March 09, 2021, 08:15:07 AM
I use Linux with WSL.

I get a failed condition error:

Which command did you use? 

I would assume that the first version would be the one to run but I can't test it out because I still haven't figured out how to get the subsystem to work.

I used the top code, which is for linux (with single quote marks):

exiftool -if '$$Image::ExifTool::MyArtist{$artist} = ($$Image::ExifTool::MyArtist{$artist} || 0) + 1 if $artist; return 0 unless $$self{FILENAME} eq "end"; my @a=map "$$_ ($$Image::ExifTool::MyArtist{$$_})\n", sort keys %Image::ExifTool::MyArtist;print @a' DIR end

I use exiftool all the time with WSL and have no issues, so it's probably not a Linux WSL issue. I created a blank file and named it "end", per instructions.

Luuk2005

Greetings Rodertroy. All I can say is that the double-quotes version does conduct perfectly inside the Windows cmd.exe.
But also, StarGeek/Hubert combined to give another solution like: Exiftool -q -ext jpg -if '$Artist' -p '$Artist' . |Sort |Uniq -c
So presenting your output like...
    134   oaktree
    762   pinetree
      12   whitebasswoodtree

Im thinking that format is much better for the eyesight, but if only wanting the example, must solve why WSL reports this error????
Or with having sed.exe, just add to StarGeek/Hubert's solution, so presenting the output like...
oaktree (134)
pinetree (762)
whitebasswoodtree (12)

Exiftool -q -ext jpg -if '$Artist' -p '$Artist' . |Sort |Uniq -c |Sed 's/ *\([0-9]*\)\t*\(.*\)/\2 (\1)/'
Windows8.1-64bit,  exiftool-v12.92(standalone),  sed-v4.0.7

StarGeek

Luuk2005's solution of adding sed to the command might be the best way to go rather than troubleshooting such a complex exiftool command.  Plus it doesn't need the "end" fille.  I would think that sort, uniq, and and sed should all be available under the WSL.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

rodertroy

Thanks all! I was able to get Phil's solution to work by installing the Exiftool exe, but I also got luuk's command to work with WSL, and I prefer this one (initially it didn't work until I remembered to lowercase uniq, sed, and sort):

exiftool -q -ext jpg -if '$Artist' -p '$Artist' . | sort | uniq -c | sed 's/ *\([0-9]*\)\t*\(.*\)/\2 (\1)/'

It processed 15k jpgs in under 2 minutes.

A separate question, but perhaps I shouldn't start a new thread. As I understand it Exiftool can't write to webp files, and can read them, so I tried scanning some webp files with info in the Exif "Artist" field with the same command (replacing jpg with webp) and it didn't work.

StarGeek

Quote from: rodertroy on March 10, 2021, 03:28:20 PMA separate question, but perhaps I shouldn't start a new thread. As I understand it Exiftool can't write to webp files, and can read them, so I tried scanning some webp files with info in the Exif "Artist" field with the same command (replacing jpg with webp) and it didn't work.

In what way didn't it work?  No output at all?  Are you sure there is an Artist tag?  Can you share an example file?
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

rodertroy

If I use the following command:

exiftool -v -q -ext webp -if '$Artist' -p '$Artist' . | sort | uniq -c | sed 's/ *\([0-9]*\)\t*\(.*\)/\2 (\1)/'

then I get the following error:

Quote-------- ./output.20210310.163122462-0.webp (failed condition) (1)
-------- ./output.20210310.163122462-1.webp (failed condition) (1)
-------- ./output.20210310.163122462-2.webp (failed condition) (1)

Phil Harvey

If the quoting is correct for your platform, then the condition should only fail if the Artist tag doesn't exist (or is "0").

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).