#! /bin/sh # # exifname -- EXIFのタイムスタンプ情報を用いてファイル名を変更する # # Usage: exifname [-t] [-r] [-n] [-v] [file]... # -t: ファイルのタイムスタンプを変更する # -r: ファイル名の変更を行わない # -n: 実際の変更を行わない # -v: 実行するコマンドを表示する # # ファイル名を「P<数字>.JPG」形式から「p<月><日><番号>.jpg」にする # printf(3) 形式で書けば「"p%1.1x%02d%04d.jpg", 月, 日, 番号」 # # 例: 5月20日に撮影した152番のファイルは p5200152.jpg に # 12月24日に撮影した69番のファイルは pc240069.jpg に # # 0.0: Apr. 29, 2006 by Dai ISHIJIMA # P2345678.JPG -> p<月><日><下4桁>.jpg # 0.1: 前から5文字目にフォルダ番号 # P2345678.JPG -> p<月><日><前から4文字目><下4桁>.jpg # 0.2: Apr. 6, 2010 (dscn0000.jpg, Nikon) # Xxx54321.JPG -> p<月><日><前から4文字目><下3桁>.jpg # (-> pMDD5321.jpg) # Xxxx4321.JPG -> p<月><日><下4桁>.jpg # (-> pMDD4321.jpg) # Xxxxx321.JPG -> p<月><日>0<下3桁>.jpg # (-> pMDD0321.jpg) # (Xは英字、xは数字以外、Mは16進表記の<月>、DDは10進2桁の<日>) # export LC_ALL=C touch=NO rename=YES verbose=NO #action=NO action=YES checkbytes=4096 mv_opt='' # オプションを調べる while [ "$#" -gt 0 ]; do case x"$1" in x-t) touch=YES shift ;; x-T) touch=NO shift ;; x-r) rename=NO shift ;; x-n) action=NO shift ;; x-v) verbose=YES shift ;; x-i) mv_opt='-i' shift ;; x-*) echo "Usage: $0 [-t] [-r] [file]..." 1>&2 exit 1 ;; x*) break ;; esac done # 実際にファイル名変更などを行わないときは実行するコマンドのみを表示 case x"$action" in xNO) verbose=YES ;; esac case x"$#" in x0) echo "Usage: $0 [-t] [-r] [file]..." 1>&2 exit 1 ;; esac status=0 for pic in "$@" ; do if [ ! -r $pic ]; then echo "${0}: $pic not found (or not readable)" 1>&2 continue fi # ファイルの先頭を調べ、EXIF情報からタイムスタンプを得る stamp=`head -c $checkbytes $pic | strings | grep -E '[0-9]{4}:[0-9]{2}:[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}' | head -1` case x"$stamp" in x) # タイムスタンプ情報が空の場合はエラー echo "$0: no EXIF time stamp found in $pic" 1>&2 status=1 ;; x[0-9]*) # ファイル名に付ける日付情報 pdate=`echo $stamp | tr ':' ' ' | awk '{printf "%1.1x%02d", $2, $3}'` # touch(1) のタイムスタンプ形式に tstamp=`echo $stamp | tr -d ': ' | sed 's/\([0-9][0-9]\)$/.\1/'` # ファイル名に含まれる番号の桁数を調べる case x"$pic" in x*[^0-9][0-9][0-9][0-9][0-9][0-9].[jJ][pP][gG]) ndigits=5 ;; x*[^0-9][0-9][0-9][0-9][0-9].[jJ][pP][gG]) ndigits=4 ;; x*[^0-9][0-9][0-9][0-9].[jJ][pP][gG]) ndigits=3 ;; esac # 元ファイル名から番号 (ベースネームの最後の3文字)を number=`echo $pic | sed 's/.*\([0-9][0-9][0-9]\)\.[Jj][Pp][Gg]$/\1/'` # 元ファイル名からフォルダ番号 (4文字目 or 5文字目) nfolder=0 case x"$ndigits" in x5) nfolder=`echo $pic | sed 's/.*\([0-9]\)[0-9][0-9][0-9][0-9].[Jj][Pp][Gg]$/\1/'` ;; x4) nfolder=`echo $pic | sed 's/.*\([0-9]\)[0-9][0-9][0-9].[Jj][Pp][Gg]$/\1/'` ;; esac newname=`echo $pic | sed 's/[A-Za-z][0-9A-Za-z_][0-9A-Za-z_][0-9A-Za-z_][0-9A-Za-z_][0-9][0-9][0-9]\.[Jj][Pp][Gg]$/'"p$pdate$nfolder$number.jpg"'/'` case x"$number" in x) echo "$0: bad file no: $number, $pic" 1>&2 ;; *) case x"$touch" in xYES) case x"$verbose" in xYES) echo touch -t "$tstamp" "$pic" ;; esac case x"$action" in xYES) touch -t "$tstamp" "$pic" ;; esac ;; esac case x"$rename" in xYES) case x"$verbose" in xYES) echo mv $mv_opt "$pic" "$newname" ;; esac case x"$action" in xYES) mv $mv_opt "$pic" "$newname" ;; esac ;; esac ;; esac ;; esac done exit $status # EOF