Created
June 18, 2026 16:55
-
-
Save ponkotuy/0ba8c127b5f4b5a4ab53e580032b97da to your computer and use it in GitHub Desktop.
写真ディレクトリにある撮って出しJPEGを消し飛ばしてrawの中身を抽出して展開するスクリプト(個人向け
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # | |
| # 撮って出しJPEG整理スクリプト | |
| # | |
| # 写真ディレクトリの構造 (raw の位置は任意の深さで良い): | |
| # SOURCE_ROOT/ | |
| # 2026/06/19/ <- 日付ディレクトリ (= raw の親) | |
| # DSC0001.JPG <- 撮って出しJPEG (日付ディレクトリ直下) | |
| # DSC0002.JPG | |
| # raw/ <- RAW + メタデータ | |
| # DSC0001.ARW | |
| # DSC0001.xmp | |
| # ... | |
| # | |
| # 処理内容: | |
| # SOURCE_ROOT 以下を再帰的に走査し、「raw ディレクトリ」を見つける。 | |
| # raw の存在をトリガーとし、その親を日付ディレクトリとして次を行う: | |
| # 1. 日付ディレクトリ直下の撮って出しJPEGを、SOURCE_ROOT からの相対パスを | |
| # 保ったまま DEST_ROOT/<相対パス>/ へ移動する。 | |
| # 2. raw/ の中身を全て直上 (日付ディレクトリ) へ移動する。 | |
| # 3. 空になった raw/ ディレクトリを削除する。 | |
| # 1ファイル移動する毎にログを出力する。 | |
| # | |
| # 移動先に同名ファイルが既に存在した場合はエラーで中断する。 | |
| set -euo pipefail | |
| usage() { | |
| cat >&2 <<EOF | |
| Usage: $(basename "$0") [-n|--dry-run] <SOURCE_ROOT> <DEST_ROOT> | |
| SOURCE_ROOT 日付ディレクトリが並んでいる写真ディレクトリ | |
| DEST_ROOT 撮って出しJPEGの移動先ディレクトリ | |
| -n, --dry-run 実際には移動/削除せず、行う操作だけをログ出力する | |
| EOF | |
| exit 2 | |
| } | |
| DRY_RUN=0 | |
| positional=() | |
| while [[ $# -gt 0 ]]; do | |
| case $1 in | |
| -n|--dry-run) DRY_RUN=1; shift ;; | |
| -h|--help) usage ;; | |
| --) shift; while [[ $# -gt 0 ]]; do positional+=("$1"); shift; done ;; | |
| -*) echo "ERROR: 不明なオプション: $1" >&2; usage ;; | |
| *) positional+=("$1"); shift ;; | |
| esac | |
| done | |
| [[ ${#positional[@]} -eq 2 ]] || usage | |
| SOURCE_ROOT=${positional[0]%/} # 末尾スラッシュを除去 (相対パス算出のため) | |
| DEST_ROOT=${positional[1]%/} | |
| [[ -d $SOURCE_ROOT ]] || { echo "ERROR: SOURCE_ROOT がディレクトリではありません: $SOURCE_ROOT" >&2; exit 1; } | |
| # 撮って出しJPEGと判定する拡張子 (大文字小文字は区別しない) | |
| shopt -s nullglob nocaseglob | |
| # dry-run 時はログ行の先頭に印を付ける | |
| PREFIX="" | |
| [[ $DRY_RUN -eq 1 ]] && PREFIX="[DRY-RUN] " | |
| log() { printf '%s %s%s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$PREFIX" "$*"; } | |
| # 移動先に同名ファイルがあれば中断、なければ mv してログ出力する | |
| # (dry-run 時は移動せずログのみ。衝突チェックは実行する) | |
| move_file() { | |
| local src=$1 dst=$2 | |
| if [[ -e $dst ]]; then | |
| echo "ERROR: 移動先に同名ファイルが既に存在します。中断します: $dst" >&2 | |
| exit 1 | |
| fi | |
| [[ $DRY_RUN -eq 0 ]] && mv -- "$src" "$dst" | |
| log "MOVED $src -> $dst" | |
| } | |
| jpeg_total=0 | |
| raw_total=0 | |
| dir_total=0 | |
| # raw ディレクトリの存在をトリガーにする。 | |
| # SOURCE_ROOT 以下を再帰的に走査し、名前が "raw" のディレクトリを全て見つける。 | |
| # (raw が無いディレクトリは対象の構造ではないので、自然と対象外になる) | |
| while IFS= read -r -d '' raw_dir; do | |
| date_dir=$(dirname "$raw_dir") | |
| # SOURCE_ROOT からの相対パス (例: 2026/06/19)。構造保持のため移動先で再現する。 | |
| rel_dir=${date_dir#"$SOURCE_ROOT"/} | |
| [[ $rel_dir == "$date_dir" ]] && rel_dir="." # date_dir が SOURCE_ROOT 直下の場合 | |
| log "==== 処理開始: $rel_dir (raw: $raw_dir) ====" | |
| ((dir_total++)) || true | |
| # --- 1. 撮って出しJPEG を DEST_ROOT/<相対パス> へ移動 --- | |
| jpeg_dest_dir="$DEST_ROOT/$rel_dir" | |
| jpegs=("$date_dir"/*.jpg "$date_dir"/*.jpeg) | |
| if [[ ${#jpegs[@]} -gt 0 ]]; then | |
| [[ $DRY_RUN -eq 0 ]] && mkdir -p -- "$jpeg_dest_dir" | |
| for jpg in "${jpegs[@]}"; do | |
| move_file "$jpg" "$jpeg_dest_dir/$(basename "$jpg")" | |
| ((jpeg_total++)) || true | |
| done | |
| else | |
| log "撮って出しJPEGなし: $rel_dir" | |
| fi | |
| # --- 2. raw/ の中身を直上 (日付ディレクトリ) へ移動 --- | |
| raw_entries=("$raw_dir"/* "$raw_dir"/.[!.]* "$raw_dir"/..?*) | |
| for entry in "${raw_entries[@]}"; do | |
| move_file "$entry" "$date_dir/$(basename "$entry")" | |
| ((raw_total++)) || true | |
| done | |
| # --- 3. 空になった raw/ を削除 --- | |
| # dry-run 時は中身を移動していないため rmdir せずログのみ | |
| [[ $DRY_RUN -eq 0 ]] && rmdir -- "$raw_dir" | |
| log "REMOVED raw ディレクトリ: $raw_dir" | |
| done < <(find "$SOURCE_ROOT" -depth -type d -name raw -print0) | |
| log "==== 完了: 対象 ${dir_total} ディレクトリ / JPEG ${jpeg_total} 件, raw ${raw_total} 件を移動しました ====" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment