#! /bin/bash #title :jpgdates #description :Select and print info about jpg files based on dates in jpg #author :gmj@pobox.com #date :Sat Dec 19 15:35:06 2015 #version :0.1 #usage :jpgdates [optinos] FILE [FILE...] #dependancies :http://owl.phy.queensu.ca/~phil/exiftool/ #notes :Also experimeting with well-written bash scripts #bash_version : # # Copyright (C) 2015 George M. Jones # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see http://www.gnu.org/licenses/. # #============================================================================== set -u # exit on undefined set -e # exit on error # set -x # echo during execution # Useful tips # http://www.kfirlavi.com/blog/2012/11/14/defensive-bash-programming/ readonly PROGNAME=$(basename $0) readonly PROGDIR=$(readlink -m $(dirname $0)) readonly ARGS=("$@") function usage() { if [ $# -gt 0 ]; then echo "${PROGNAME}: $@"; echo; fi cat <<- EOF usage: $PROGNAME [options] FILE [FILE...] This program determins if a JPEG file has an Original Date stored with it and prints the filename and/or date. OPTIONS: -w --withdates Select files with dates -m --missingdates Select files with no dates -p --path Print path of matching files -t --dates Print dates of matching files -i --isomtime Print ISO-formatted mtime before file -v --verbose Verbose. You can specify more then one -v to have more verbose -d --debug debug -h --help show this help Examples: Fine info about a single file $PROGNAME sample.jpg Find info about all jpg files in directory find . -type f -name \*.jpg -print0 | xargs -L 1 -0 $PROGNAME Find only Pathnames of jpg files Missing dates: find . -type f -name \*.jpg -print0 | xargs -L 1 -0 $PROGNAME -m -p Find all info about jpg files With dates find . -type f -name \*.jpg -print0 | xargs -L 1 -0 $PROGNAME -w Horrible real world invocation to look at the last 10 files of the first 40 available: find . -type f -name \*.jpg -print0 | tr '\0\n' '\n\0' | head -40 | tail -10 | tr '\0\n' '\n\0'| xargs -L 1 -n 1 -0 $PROGNAME EOF } function parseArgs() { # Option parsing courtesy of # http://stackoverflow.com/questions/402377/using-getopts-in-bash-shell-script-to-get-long-and-short-command-line-options # NOTE: This requires GNU getopt. On Mac OS X and FreeBSD, you have to install this # separately; see below. TEMP=`getopt -o wmptvdih --long withdates,missingdates,path,dates,isomtime,verbose,debug,help \ -n 'jpghasDate' -- "$@"` if [ $? != 0 ] ; then echo "getopt failed. Terminating..." >&2 ; exit 1 ; fi # Note the quotes around `$TEMP': they are essential! eval set -- "$TEMP" # Set default values # Selection Parameters OPT_SELECT_WITH_DATES=false # print files that have dates OPT_SELECT_MISSING_DATES=false # print files with no date # Output Parameters OPT_VERBOSE=false # verbose output OPT_DEBUG=false # debugging output OPT_PRINT_PATH=false # print path OPT_PRINT_DATES=false # print date OPT_ISO_MTIME=false # print iso mtime of file before path OPT_PRINT_ALL=true # print all (default) while true; do case "$1" in -w | --withdates ) OPT_SELECT_WITH_DATES=true; shift ;; -m | --missingdates ) OPT_SELECT_MISSING_DATES=true; shift ;; -p | --path ) OPT_PRINT_PATH=true; shift ;; -t | --dates ) OPT_PRINT_DATES=true; shift ;; -i | --isomtime ) OPT_ISO_MTIME=true; shift ;; -v | --verbose ) OPT_VERBOSE=true; shift ;; -d | --debug ) OPT_DEBUG=true; shift ;; -h | --help ) usage; exit 0;shift ;; -- ) shift; break ;; * ) break ;; esac done if [ $# -lt 1 ] ; then usage "Missing argument. Need at least one filename."; exit 1; fi # Defualt to printing all if ! ( $OPT_PRINT_PATH || $OPT_PRINT_DATES ); then OPT_PRINT_PATH=true OPT_PRINT_DATES=true fi # Defualt to selectiing all if ! ( $OPT_SELECT_WITH_DATES || $OPT_SELECT_MISSING_DATES ); then OPT_SELECT_WITH_DATES=true OPT_SELECT_MISSING_DATES=true fi # Make parsing paramters readonly readonly OPT_SELECT_WITH_DATES=${OPT_SELECT_WITH_DATES} # print files that have dates readonly OPT_SELECT_MISSING_DATES=${OPT_SELECT_MISSING_DATES} # print files with no date readonly OPT_VERBOSE=${OPT_VERBOSE} # verbose output readonly OPT_DEBUG=${OPT_DEBUG} # debugging output readonly OPT_PRINT_PATH=${OPT_PRINT_PATH} # print path readonly OPT_PRINT_DATES=${OPT_PRINT_DATES} # print date readonly OPT_PRINT_ALL=${OPT_PRINT_ALL} # print all (default) OPT_ARGS=("$@") } function printSelectedFiles () { if $OPT_DEBUG; then echo ARGS TO printSelectedFiles for ARG in "$@"; do printf 'ARG %s\n' "$ARG" done fi for file in "$@"; do if $OPT_DEBUG; then echo file $file >&2; fi exifDate=$(exiftool "$file" | grep Orig || echo "NONE") exifDate=$(echo $exifDate | sed -e 's/Date\/Time Original\s*\:\s*//') output="" if $OPT_ISO_MTIME; then epochTime=`stat --printf='%Y' "$file" ` isoTime=`date --date="@$epochTime" -Iminutes` output="$isoTime $output" fi if $OPT_PRINT_PATH; then output="$output$file"; fi if $OPT_PRINT_DATES; then output="$output : $exifDate"; fi if $OPT_SELECT_MISSING_DATES; then if [[ $exifDate == *"NONE"* ]]; then echo $output fi fi if $OPT_SELECT_WITH_DATES; then if [[ $exifDate != *"NONE"* ]]; then echo $output fi fi done } function main() { parseArgs "$@" printSelectedFiles "${OPT_ARGS[@]}" } #main if [ ${#ARGS[@]} -lt 1 ] ; then usage "Missing argument. Need at least one filename."; exit 1; fi main "${ARGS[@]}"