My kids and I share some camera bodies (7D II, 5D III, rebel t4i) as well as a pile of lenses. The job of sorting through the pictures falls on me and I struggle with it so I wrote this script. I call lens because originally I was trying to sort by which lens we were using but then we swapped bodies on one canoe trip to Elkhorn Slough so I added camera bodies to the script as well.
So what’s it do? You can look at a set of jpgs (or raw files) and say “show me all the ones that were shot by the 7D” or “show me all the ones shot with the 70-200”. Those would be
lens --camera=7D *.jpg
lens --lens=70-200 *.jpg
Here’s the script.
#!/usr/local/bitkeeper/bk tclsh
#lang L
/*
* Use exiftags -c to dig produce a list like so
* foo.jpg: EF200mm f/2L IS USM
* bar.jpg: EF70-200mm f/4L IS USM
* ...
*/
void
main(string av[])
{
FILE exif;
string buf, c, jpeg;
string camera[] = undef;
string notcamera[] = undef;
string lens[] = undef;
string notlens[] = undef;
string lopts[] = {
"camera:", // --camera=regex
"notcamera:", // --camera=regex
"lens:", // --lens=regex
"not-lens:", // --lens=regex
};
int i, matchlens, matchcamera, nope;
string model, anno;
while (c = getopt(av, "", lopts)) {
switch (c) {
case "camera": push(&camera, optarg); break;
case "not-camera": push(¬camera, optarg); break;
case "lens": push(&lens, optarg); break;
case "not-lens": push(¬lens, optarg); break;
}
}
for (i = optind; buf = av[i]; i++) {
exif = popen("exiftags -c ${buf}", "r");
jpeg = buf;
anno = undef;
nope = matchlens = matchcamera = 0;
while (buf = <exif>) {
if (buf =~ /Lens Name:\s*(.*)/) {
model = $1;
foreach (c in lens) {
if (model =~ /${c}/) {
matchlens = 1;
break;
}
}
foreach (c in notlens) {
if (model =~ /${c}/) goto nope;
}
if (anno) {
anno .= ", ${model}";
} else {
anno = model;
}
} else if (buf =~ /Camera Model:\s*(.*)/) {
model = $1;
foreach (c in camera) {
if (model =~ /${c}/) {
matchcamera = 1;
break;
}
}
foreach (c in notcamera) {
if (model =~ /${c}/) goto nope;
}
model =~ s/Canon EOS //;
if (anno) {
anno .= ", ${model}";
} else {
anno = model;
}
} else {
continue;
}
}
if (lens && !matchlens) goto nope;
if (camera && !matchcamera) goto nope;
printf("%s %s\n", jpeg, anno);
nope: pclose(exif);
}
}