写真・動画を撮影時間ごとに自動整理！メタデータを活用したシェルスクリプト入門

## はじめに

写真愛好家やビデオグラファーの皆さん、こんな経験はありませんか？撮影から帰ってきた後、数百枚の写真や動画ファイルが無秩序に並んでいて整理に何時間も費やしてしまう…。私もその一人でした。そこで今回は、この問題を解決するための自作シェルスクリプトをご紹介します。

https://github.com/hiroki-abe-58/sort_files

このスクリプトは、ファイルのメタデータから撮影日時を自動的に読み取り、時間単位でフォルダを作成して分類してくれます。例えば、2025年4月1日の午後3時に撮影した全ての写真は `2025-04-01_15` というフォルダに自動的に移動されます。これにより、「あの時撮った写真はどこだろう？」という探し物が驚くほど簡単になります。

## こんな人におすすめ

- カメラやスマホで大量の写真・動画を撮影する方
- 撮影データを時系列で整理したい方
- ファイル整理作業を自動化したい方
- シェルスクリプトの実用例を知りたい初心者の方

## スクリプトの特徴

- ARW（ソニーのRAWファイル）、JPG、MP4ファイルに対応
- 撮影時間ごとにフォルダを自動作成
- メタデータが存在しないファイルは「null」フォルダに分類
- 編集済みファイルを別フォルダに整理
- macOSとLinuxに対応

## 技術的な仕組み

このスクリプトの肝は、`exiftool`というコマンドラインツールを使ってファイルのメタデータを抽出する点にあります。デジタルカメラやスマートフォンで撮影した写真・動画には、撮影日時やカメラの設定などの情報がEXIFと呼ばれるメタデータとして埋め込まれています。このデータを読み取り、正規表現を使って必要な形式に変換しています。

## スクリプトを見てみよう

```bash
#!/bin/bash

# ユーザーに基本パスを尋ねる
echo "写真・動画の整理を行います。ベースディレクトリのパスを入力してください:"
read -r BASE_DIR

# 入力されたパスが存在するか確認
if [ ! -d "$BASE_DIR" ]; then
  echo "エラー: 指定されたディレクトリ「$BASE_DIR」は存在しません。"
  exit 1
fi

# baseディレクトリのパスを設定
BASE_SORTED_DIR="${BASE_DIR}/base"

# サブディレクトリのパスを設定
ARW_DIR="${BASE_SORTED_DIR}/arw"
JPG_DIR="${BASE_SORTED_DIR}/jpg"
MP4_DIR="${BASE_SORTED_DIR}/mp4"
EDITED_DIR="${BASE_DIR}/edited"

# 必要なディレクトリを作成
mkdir -p "$ARW_DIR" "$JPG_DIR" "$MP4_DIR" "$EDITED_DIR"
mkdir -p "$ARW_DIR/null" "$JPG_DIR/null" "$MP4_DIR/null"

# ARWファイルを処理する関数
process_arw_files() {
  echo "ARWファイルを処理しています..."
  
  find "$BASE_DIR" -type f -iname "*.ARW" -not -path "$BASE_SORTED_DIR/*" | while read -r file; do
    # 撮影日時を取得
    date_time=$(exiftool -s -s -s -DateTimeOriginal "$file" 2>/dev/null)
    
    if [ -n "$date_time" ]; then
      # 日付形式を変換（YYYY:MM:DD HH:MM:SS → YYYY-MM-DD_HH）
      folder_date=$(echo "$date_time" | sed 's/\([0-9]\{4\}\):\([0-9]\{2\}\):\([0-9]\{2\}\) \([0-9]\{2\}\):[0-9]\{2\}:[0-9]\{2\}/\1-\2-\3_\4/')
      
      # ディレクトリ作成とファイル移動
      target_dir="$ARW_DIR/$folder_date"
      mkdir -p "$target_dir"
      mv "$file" "$target_dir/"
      echo "移動しました: $file → $target_dir/"
    else
      # メタデータなしの場合
      mv "$file" "$ARW_DIR/null/"
      echo "メタデータなし: $file → $ARW_DIR/null/"
    fi
  done
}

# 省略：JPG、MP4処理関数も同様
# ...

# 各ファイルタイプの処理を実行
process_arw_files
process_jpg_files
process_mp4_files

# 編集済みファイルを移動
echo "編集済みファイルを移動しています..."
find "$BASE_DIR" -type f -iname "*_edited*" -not -path "$EDITED_DIR/*" -exec mv {} "$EDITED_DIR/" \;

echo "処理が完了しました"
```

## 解説：コードの重要なポイント

### 1. メタデータの抽出

```bash
date_time=$(exiftool -s -s -s -DateTimeOriginal "$file" 2>/dev/null)
```

この行が魔法の鍵です。`exiftool`コマンドを使用してファイルから撮影日時（DateTimeOriginal）を抽出しています。`-s -s -s`オプションは、余計な情報を省いて値だけを取得するためのもので、エラー出力（2>/dev/null）は無視しています。

### 2. 日時フォーマットの変換

```bash
folder_date=$(echo "$date_time" | sed 's/\([0-9]\{4\}\):\([0-9]\{2\}\):\([0-9]\{2\}\) \([0-9]\{2\}\):[0-9]\{2\}:[0-9]\{2\}/\1-\2-\3_\4/')
```

ここでは`sed`コマンドを使用して、「YYYY:MM:DD HH:MM:SS」形式の日時を「YYYY-MM-DD_HH」形式に変換しています。正規表現を使って必要な部分だけを抽出し、フォルダ名に適した形式に整形しています。

## 使い方

1. まず`exiftool`をインストールします。

```bash
# macOSの場合
brew install exiftool

# Ubuntuの場合
sudo apt-get install libimage-exiftool-perl
```

2. スクリプトに実行権限を付与します。

```bash
chmod +x run_sortfiles.command
```

3. スクリプトを実行し、整理したいディレクトリのパスを入力します。

```bash
./run_sortfiles.command
```

4. 後はスクリプトが自動的に処理してくれます！

## 応用：さらなるカスタマイズのアイデア

このスクリプトは基本的な機能を実装していますが、さらに発展させるアイデアもあります：

1. **他のファイル形式対応**: PNGやHEIC、MOVなど他の形式にも対応
2. **階層型分類**: 年/月/日/時間の階層構造を作成
3. **撮影場所による分類**: GPSデータを使用して場所ごとに分類
4. **重複ファイルの検出**: MD5ハッシュを使って重複を検出
5. **サムネイル生成**: ImageMagickを使って一覧用サムネイルを生成

## シェルスクリプト学習のステップアップに

このスクリプトは、実用的なシェルスクリプトの好例です。以下のような基本的なシェルスクリプトの要素を学ぶことができます：

- 変数の使用方法
- 条件分岐（if文）
- 関数の定義と呼び出し
- findコマンドによるファイル検索
- sedによる文字列処理
- 外部コマンド（exiftool）の利用方法

## まとめ

写真・動画ファイルの整理は地味な作業ですが、適切なツールを使えば大幅に効率化できます。今回紹介したスクリプトは、私自身の写真整理の悩みから生まれたものですが、多くの方の役に立てれば嬉しいです。

シェルスクリプトは敷居が高いと思われがちですが、このように身近な問題を解決するツールを作ることで、プログラミングの楽しさを感じられるのではないでしょうか。

ぜひ自分なりにカスタマイズして、あなただけの最強整理ツールを作ってみてください！

## 参考リンク

- [exiftoolの公式ドキュメント](https://exiftool.org/)
- [Bashスクリプトの基本](https://www.gnu.org/software/bash/manual/bash.html)
- [シェルスクリプトでのファイル操作入門](https://linuxcommand.org/lc3_writing_shell_scripts.php)

---

この記事はいかがでしたか？皆さんの写真・動画整理に役立つアイデアがあれば、ぜひコメントで教えてください。また、スクリプトを改良した方は、ぜひその内容をシェアしていただけると嬉しいです！