ファイル名をそのファイルの更新日時に変えるRubyスクリプトを作ってみたので、メモしておきます。

ARGV.each do |file|
  newname = File.mtime(file).strftime("%Y%m%d-%H%M%S") + File.extname(file).downcase
  print "#{file} --> #{newname}\n"
  File.rename(file, newname)
end

このスクリプトを、例えばrename.rbというファイルに書いてrubyで実行すると、引数で指定したファイルのファイル名が更新日時(ここではYYYYMMDD-HHMMSSの形式)になります。拡張子は小文字になります。以下、実行例です。

$ ls -lT *.PNG
-rw-r--r--  1 alpha  alpha  122619  5月  2 11:51:17 2015 IMG_1125.PNG
-rw-r--r--  1 alpha  alpha  455271  5月  4 18:36:05 2015 IMG_1126.PNG
-rw-r--r--  1 alpha  alpha  126072  5月 29 18:43:33 2015 IMG_1129.PNG
$ ruby rename.rb *.PNG
IMG_1125.PNG --> 20150502-115117.png
IMG_1126.PNG --> 20150504-183605.png
IMG_1129.PNG --> 20150529-184333.png

なんでこんなことをしようと思ったのかと言うと……。

デジカメやスマートフォンで撮った写真って、だいたいファイル名が固定文字列+連番になってますよね。「IMG_1234.JPG」みたいに。

なので、PCにフォルダを作っていろんなカメラで撮った写真を突っ込むと、ファイル名順に並べても時系列じゃなくなってしまいます。まあ、更新日時でソートすれば「ほぼ」時系列にはなるんですが、写真を加工した場合など、更新日と撮影日が不一致になっている場合もあります。そんなときでも、Windowsだとエクスプローラーで「撮影日時」フィールドを表示させてソートすれば、ちゃんとExifの撮影日時順にもできます。ただ、いつもそれを意識するのも面倒ですし、またメディアプレーヤーなどのアプライアンスでスライドショーすることなども考えると、やっぱりファイル名が撮影日時順に並ぶようにしておくのがいちばん便利かと思います。

そういう場合、UNIX系OSならJHeadで簡単に一括リネームができます。jheadコマンドの-nオプションを使うと、ExifヘッダのDateTimeOriginalフィールドの値に基づいてファイル名をリネームしてくれます。デフォルトの書式はMMDD-HHMMSSです。

$ jhead -n P1000054.JPG
P1000054.JPG --> 0316-111526.jpg

-nオプションは、引数にstrftime関数の書式文字列を指定すれば、任意の書式を使う事もできます。例えば、YYYYMMDD-HHMMSSという書式にしたいなら、下記の例のようになります。

$ jhead -n%Y%m%d-%H%M%S P1000054.JPG
P1000054.JPG --> 20150316-111526.jpg

これでバッチリかと思いきや、iPhoneの場合、スクリーンキャプチャのPNGや動画のMOVが写真と一緒に混ざっていると、これらはそもそもExifヘッダを持っていないので、JHeadはリネームしてくれません。いちいち手でリネームするのも面倒なので、更新日時を頼りに一括リネームする冒頭のスクリプトを考えた次第です。言わずもがなですが、この単純なスクリプトは、ディレクトリ階層がある場合とか、複数ファイルの更新日時が秒までかぶっている場合とか、リムームのエラー処理なんかを一切考慮してませんので、実際に使うときはそのへん適当にカスタマイズする必要があります。

※バージョンメモ

  • FreeBSD 10.1-RELEASE-p16 amd64
  • ruby-2.1.6,1
  • jhead-3.00