本サイトではアフィリエイト広告を利用しています
EXIF ベースでコマンドからファイルを並べ替える方法

Cygwin PC-UNIX Windows コード

[小ネタ]EXIF ベースでコマンドからファイルを並べ替える方法

スマホで撮影した写真を PC に転送する時など、意図せずにファイル名が変わったり、ファイルの日付がすべて現在時刻(スマホからPCへ転送した時刻)に変更されてしまうことがあります。

撮影した写真に EXIF 情報が残っていれば、それでもまだ整理しやすくする方法があります。
このページでは、コマンドラインから EXIF 入の画像データを並べ替える方法をチェックします。

ランダムな名前のカメラ撮影画像を並べ替える

最終的には、EXIF ベースでソートして、ファイル名を EXIF ベースで書き換える bash スクリプトを作ります。

E7CWu.jpg といったファイルを、EXIF から撮影時刻を参照して 2021-05-04_11-12-12_E7CWu.jpg という感じのファイル名にします。

bash が動けばいいので、Windows なら Cygwin、MacOS や Linux や BSD 系の OS で使えます。

まず、EXIF の内容をチェックします。
Windows パソコンで目的の画像に EXIF データが含まれているのかどうか確認しておきます。
ここでは私の愛用フリーソフト XnView を使ってみます。他の商用ソフトなどでも可能ですが、素早くデータを確認したいだけですので、軽く動くビューアがおすすめです。
以下のフリーソフトは定番ですので、使ったことない方はまず試してみることをおすすめします。

XnView https://www.xnview.com/en/

IrfanView https://www.irfanview.com/
https://forest.watch.impress.co.jp/library/software/irfanview/

Imagemagick を使って EXIF を見る

EXIF 情報を参考にするには様々な方法がありますが、今回の最終目的を見越して Imagemagick を利用するのが応用を考えるうえでも手軽そうです。
ということで、Imagemagick をインストールしていない方は、まず Imagemagick のインストールを始めてください。

Cygwin の場合は setup.exe から Imagemagick を選択できます

FreeBSD の場合はパッケージからインストールしてしまうのが簡単です。

 bash
$ pkg add graphics/ImageMagick7

もしくは
 bash
$ pkg add graphics/ImageMagick7-nox11

辺りでしょうか。

Linux の場合(ここでは Ubuntu)は

 bash
ubu@ntu:~$ sudo apt install imagemagick
[sudo] password for ubuntu:

FreeBSD や Linux の人は上の太文字の部分をコマンドしてください。

ランダムな名前の jpeg ファイルの日付を調べる

スマホ(やカメラ)本体と PC を USB 接続してファイルを PC 側にコピーすると、ファイルの日付が撮影時の時刻ではなくて、コピーした時の時刻に書き換わることがあります。

また、スマホアプリなどで撮影、作成した画像はファイル名に日付等の情報が含まれないケースが多々あります。

そういったケースでは、実際の写真の撮影時順に並べ替えてアルバム化したりすることが、ほぼ手動になりますので面倒です。例を見てみましょう。

 bash
ubu@ntu:~$ ls
2eKiT.jpg  bNFrt.jpg  Dvkfp.jpg  E7CWu.jpg  F2eI2.jpg  yRDf5.jpg
awfXx.jpg  D3eby.jpg  DwoPq.jpg  EhyHQ.jpg  PTAPf.jpg
ubu@ntu:~$ ls -la
合計 35248
drwxrwx---+ 1 ubuntu なし       0  1月 31 12:40 .
drwxrwx---+ 1 ubuntu なし       0  1月 31 12:40 ..
-rwxrwx---+ 1 ubuntu なし 5003208  1月  1  1970 2eKiT.jpg
-rwxrwx---+ 1 ubuntu なし 3959934  1月  1  1970 awfXx.jpg
-rwxrwx---+ 1 ubuntu なし 1424336  1月  1  1970 bNFrt.jpg
-rwxrwx---+ 1 ubuntu なし 3051731  1月  1  1970 D3eby.jpg
-rwxrwx---+ 1 ubuntu なし 4073644  1月  1  1970 Dvkfp.jpg
-rwxrwx---+ 1 ubuntu なし 1785237  1月  1  1970 DwoPq.jpg
-rwxrwx---+ 1 ubuntu なし 1966383  1月  1  1970 E7CWu.jpg
-rwxrwx---+ 1 ubuntu なし 4212441  1月  1  1970 EhyHQ.jpg
-rwxrwx---+ 1 ubuntu なし 4036863  1月  1  1970 F2eI2.jpg
-rwxrwx---+ 1 ubuntu なし 2578407  1月  1  1970 PTAPf.jpg
-rwxrwx---+ 1 ubuntu なし 3971047  1月  1  1970 yRDf5.jpg

用意したファイルは、日付もファイル名もデタラメで、何を撮影したファイルかはそれらの情報だけでは判別つきません。しかし、これらのファイルには EXIF 情報が含まれています。
今回は、その EXIF 情報をもとにファイルを整理してみます。

Imagemagick から EXIF 情報を得る

以下の例では、EXIF 含まれている 2eKiT.jpg というカメラ撮影ファイルについての情報を覗いています。

jpeg ファイルのあるディレクトリに移動して、

identify -verbose ファイル名

とやると、EXIF 情報が得られます。

 bash
ubu@ntu:~$ identify -verbose 2eKiT.jpg
Image:
  Filename: 2eKiT.jpg
  Format: JPEG (Joint Photographic Experts Group JFIF format)
  Mime type: image/jpeg
  Class: DirectClass
  Geometry: 4032x3024+0+0
  Resolution: 72x72
  Print size: 56x42
  Units: PixelsPerInch
  Colorspace: sRGB
  Type: TrueColor
  Base type: Undefined
  Endianness: Undefined
  Depth: 8-bit
  Channel depth:
    Red: 8-bit
    Green: 8-bit
    Blue: 8-bit
~(途中略)~
  Properties:
    date:create: 2023-01-31T03:46:54+00:00
    date:modify: 1969-12-31T15:00:00+00:00
    exif:ApertureValue: 252/100
    exif:BrightnessValue: 133/100
    exif:ColorSpace: 1
    exif:ComponentsConfiguration: 1, 2, 3, 0
    exif:Contrast: 0
    exif:CustomRendered: 0
    exif:DateTime: 2021:11:14 16:57:07
    exif:DateTimeDigitized: 2021:11:14 16:57:07
    exif:DateTimeOriginal: 2021:11:14 16:57:07
    exif:DigitalZoomRatio: 0/0
    exif:ExifOffset: 225
    exif:ExifVersion: 48, 50, 50, 48
    exif:ExposureBiasValue: 0/10
    exif:ExposureMode: 0
    exif:ExposureProgram: 2
~(途中略)~
  Artifacts:
    verbose: true
  Tainted: False
  Filesize: 4.77143MiB
  Number pixels: 12.1928M
  Pixels per second: 103.972MP
  User time: 0.109u
  Elapsed time: 0:01.117
(以下略)

赤字の部分に、今回求めていた情報がありました。

EXIF から日付データを取り出す

EXIF データには、現ファイルの作成日時情報も含まれています。
しかし、今回のテーマで必要な情報は、画像ファイルの撮影日時です。

必要な情報は exif:DateTime: で始まる行にあります。

今回は grep を利用して、必要な行を取り出します。grep で "exif:DateTime:" を含む行を出力します。

 bash
ubu@ntu:~$ identify -verbose 2eKiT.jpg | grep "exif:DateTime:"
    exif:DateTime: 2021:11:14 16:57:07

grep 以外にも、awk や perl、ruby を使うともっと複雑なデータでも取り出せます。今回はお手軽な grep を利用します。

grep "Date" や grep で "exif:DateTime" とやると、必要としない行まで引っ張ってしまいます。"exif:DateTime:" と末尾のコロンまで入れて、限定的に出力しましょう。

bash でリネームするスクリプトを作る

Imagemagick で EXIF 情報が得られることは分かりましたが、それだけだと面倒です。
ということで、ファイル名に Exif 撮影日付をつけまずリネームします。そうすることで、少しは扱いやすくなるはずです。

一気に処理しますので、スクリプトにします。
以下のテキストを rename-by-exifdate.bash という名前でテキストファイルとして保存します。
「#」から始まるコメント行は飛ばして問題ありません。文字コードは UTF-8、改行コードは LF にしておくと問題は少ないと思います。

 
# ループを作ります
for jpgfile in *.jpg; do
  # if not exist
  [[ -e $jpgfile ]] || continue 
# imagemagick の identify を利用します
  exif=$(identify -verbose ${jpgfile} | grep "exif:DateTime:" | head -1)
# 得られた値を切り出します
  datetime=$(echo ${exif:19:20} | sed s/:/-/g | sed "s/ /-/g")
# 新しい名前を決めます
  newfilename=${datetime}_${jpgfile}
# リネームします
  mv "$jpgfile" "$newfilename"
  echo -e "Renamed: $newfilename"
done
# 処理終了です。

実行は bash で行います。

 bash
ubu@ntu:~$ bash rename-by-exifdate.bash
Renamed: 2021-11-14-16-57-07_2eKiT.jpg
Renamed: 2022-11-04-16-30-20_awfXx.jpg
Renamed: 2019-07-20-13-41-48_bNFrt.jpg
~(途中略)~
Renamed: 2022-02-08-12-23-57_D3eby.jpg
Renamed: 2021-10-29-15-45-21_Dvkfp.jpg
Renamed: 2021-04-10-18-55-49_yRDf5.jpg

ソートすると

 bash
ubu@ntu:~$ ls *.jpg | sort -n
2018-08-19-15-04-56_F2eI2.jpg
2019-07-19-18-18-13_E7CWu.jpg
2019-07-20-13-41-48_bNFrt.jpg
2021-04-10-18-55-49_yRDf5.jpg
2021-04-11-14-45-05_PTAPf.jpg
2021-10-29-15-45-21_Dvkfp.jpg
2021-11-14-16-57-07_2eKiT.jpg
2021-12-23-07-08-07_DwoPq.jpg
2022-02-08-12-23-57_D3eby.jpg
2022-05-11-15-30-25_EhyHQ.jpg
2022-11-04-16-30-20_awfXx.jpg

ファイル名に撮影日付が入ったので、少しは便利に扱えるようになりました。
応用として、touch コマンドを使ってファイルの日付を EXIF 撮影日付に書き換えることも可能です。

また、今回は EXIF の日付を利用しましたが、カメラ名や露出などのデータをファイル名に含めることも可能です。

-Cygwin, PC-UNIX, Windows, コード
-, ,