jpgdates 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. #! /bin/bash
  2. #title :jpgdates
  3. #description :Select and print info about jpg files based on dates in jpg
  4. #author :gmj@pobox.com
  5. #date :Sat Dec 19 15:35:06 2015
  6. #version :0.1
  7. #usage :jpgdates [optinos] FILE [FILE...]
  8. #dependancies :http://owl.phy.queensu.ca/~phil/exiftool/
  9. #notes :Also experimeting with well-written bash scripts
  10. #bash_version :
  11. #
  12. # Copyright (C) 2015 George M. Jones
  13. #
  14. # This program is free software: you can redistribute it and/or modify
  15. # it under the terms of the GNU General Public License as published by
  16. # the Free Software Foundation, either version 3 of the License, or
  17. # (at your option) any later version.
  18. #
  19. # This program is distributed in the hope that it will be useful, but
  20. # WITHOUT ANY WARRANTY; without even the implied warranty of
  21. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  22. # General Public License for more details.
  23. #
  24. # You should have received a copy of the GNU General Public License
  25. # along with this program. If not, see http://www.gnu.org/licenses/.
  26. #
  27. #==============================================================================
  28. set -u # exit on undefined
  29. set -e # exit on error
  30. # set -x # echo during execution
  31. # Useful tips
  32. # http://www.kfirlavi.com/blog/2012/11/14/defensive-bash-programming/
  33. readonly PROGNAME=$(basename $0)
  34. readonly PROGDIR=$(readlink -m $(dirname $0))
  35. readonly ARGS=("$@")
  36. function usage() {
  37. if [ $# -gt 0 ]; then echo "${PROGNAME}: $@"; echo; fi
  38. cat <<- EOF
  39. usage: $PROGNAME [options] FILE [FILE...]
  40. This program determins if a JPEG file has an Original Date stored
  41. with it and prints the filename and/or date.
  42. OPTIONS:
  43. -w --withdates Select files with dates
  44. -m --missingdates Select files with no dates
  45. -p --path Print path of matching files
  46. -t --dates Print dates of matching files
  47. -i --isomtime Print ISO-formatted mtime before file
  48. -v --verbose Verbose. You can specify more then one -v to have more verbose
  49. -d --debug debug
  50. -h --help show this help
  51. Examples:
  52. Fine info about a single file
  53. $PROGNAME sample.jpg
  54. Find info about all jpg files in directory
  55. find . -type f -name \*.jpg -print0 | xargs -L 1 -0 $PROGNAME
  56. Find only Pathnames of jpg files Missing dates:
  57. find . -type f -name \*.jpg -print0 | xargs -L 1 -0 $PROGNAME -m -p
  58. Find all info about jpg files With dates
  59. find . -type f -name \*.jpg -print0 | xargs -L 1 -0 $PROGNAME -w
  60. Horrible real world invocation to look at the last 10 files of the first 40 available:
  61. 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
  62. EOF
  63. }
  64. function parseArgs() {
  65. # Option parsing courtesy of
  66. # http://stackoverflow.com/questions/402377/using-getopts-in-bash-shell-script-to-get-long-and-short-command-line-options
  67. # NOTE: This requires GNU getopt. On Mac OS X and FreeBSD, you have to install this
  68. # separately; see below.
  69. TEMP=`getopt -o wmptvdih --long withdates,missingdates,path,dates,isomtime,verbose,debug,help \
  70. -n 'jpghasDate' -- "$@"`
  71. if [ $? != 0 ] ; then echo "getopt failed. Terminating..." >&2 ; exit 1 ; fi
  72. # Note the quotes around `$TEMP': they are essential!
  73. eval set -- "$TEMP"
  74. # Set default values
  75. # Selection Parameters
  76. OPT_SELECT_WITH_DATES=false # print files that have dates
  77. OPT_SELECT_MISSING_DATES=false # print files with no date
  78. # Output Parameters
  79. OPT_VERBOSE=false # verbose output
  80. OPT_DEBUG=false # debugging output
  81. OPT_PRINT_PATH=false # print path
  82. OPT_PRINT_DATES=false # print date
  83. OPT_ISO_MTIME=false # print iso mtime of file before path
  84. OPT_PRINT_ALL=true # print all (default)
  85. while true; do
  86. case "$1" in
  87. -w | --withdates ) OPT_SELECT_WITH_DATES=true; shift ;;
  88. -m | --missingdates ) OPT_SELECT_MISSING_DATES=true; shift ;;
  89. -p | --path ) OPT_PRINT_PATH=true; shift ;;
  90. -t | --dates ) OPT_PRINT_DATES=true; shift ;;
  91. -i | --isomtime ) OPT_ISO_MTIME=true; shift ;;
  92. -v | --verbose ) OPT_VERBOSE=true; shift ;;
  93. -d | --debug ) OPT_DEBUG=true; shift ;;
  94. -h | --help ) usage; exit 0;shift ;;
  95. -- ) shift; break ;;
  96. * ) break ;;
  97. esac
  98. done
  99. if [ $# -lt 1 ] ; then usage "Missing argument. Need at least one filename."; exit 1; fi
  100. # Defualt to printing all
  101. if ! ( $OPT_PRINT_PATH || $OPT_PRINT_DATES ); then
  102. OPT_PRINT_PATH=true
  103. OPT_PRINT_DATES=true
  104. fi
  105. # Defualt to selectiing all
  106. if ! ( $OPT_SELECT_WITH_DATES || $OPT_SELECT_MISSING_DATES ); then
  107. OPT_SELECT_WITH_DATES=true
  108. OPT_SELECT_MISSING_DATES=true
  109. fi
  110. # Make parsing paramters readonly
  111. readonly OPT_SELECT_WITH_DATES=${OPT_SELECT_WITH_DATES} # print files that have dates
  112. readonly OPT_SELECT_MISSING_DATES=${OPT_SELECT_MISSING_DATES} # print files with no date
  113. readonly OPT_VERBOSE=${OPT_VERBOSE} # verbose output
  114. readonly OPT_DEBUG=${OPT_DEBUG} # debugging output
  115. readonly OPT_PRINT_PATH=${OPT_PRINT_PATH} # print path
  116. readonly OPT_PRINT_DATES=${OPT_PRINT_DATES} # print date
  117. readonly OPT_PRINT_ALL=${OPT_PRINT_ALL} # print all (default)
  118. OPT_ARGS=("$@")
  119. }
  120. function printSelectedFiles () {
  121. if $OPT_DEBUG; then
  122. echo ARGS TO printSelectedFiles
  123. for ARG in "$@"; do
  124. printf 'ARG %s\n' "$ARG"
  125. done
  126. fi
  127. for file in "$@"; do
  128. if $OPT_DEBUG; then echo file $file >&2; fi
  129. exifDate=$(exiftool "$file" | grep Orig || echo "NONE")
  130. exifDate=$(echo $exifDate | sed -e 's/Date\/Time Original\s*\:\s*//')
  131. output=""
  132. if $OPT_ISO_MTIME; then
  133. epochTime=`stat --printf='%Y' "$file" `
  134. isoTime=`date --date="@$epochTime" -Iminutes`
  135. output="$isoTime $output"
  136. fi
  137. if $OPT_PRINT_PATH; then output="$output$file"; fi
  138. if $OPT_PRINT_DATES; then output="$output : $exifDate"; fi
  139. if $OPT_SELECT_MISSING_DATES; then
  140. if [[ $exifDate == *"NONE"* ]]; then
  141. echo $output
  142. fi
  143. fi
  144. if $OPT_SELECT_WITH_DATES; then
  145. if [[ $exifDate != *"NONE"* ]]; then
  146. echo $output
  147. fi
  148. fi
  149. done
  150. }
  151. function main() {
  152. parseArgs "$@"
  153. printSelectedFiles "${OPT_ARGS[@]}"
  154. }
  155. #main
  156. if [ ${#ARGS[@]} -lt 1 ] ; then usage "Missing argument. Need at least one filename."; exit 1; fi
  157. main "${ARGS[@]}"