Skip to content

Instantly share code, notes, and snippets.

@on0z
Last active June 28, 2025 10:50
Show Gist options
  • Save on0z/8ef511d808d1a1b790d89a9010250062 to your computer and use it in GitHub Desktop.
Save on0z/8ef511d808d1a1b790d89a9010250062 to your computer and use it in GitHub Desktop.
importFromSonyAlpha ソニー製カメラαから,写真と動画を整理して取り出すスクリプト
#!/bin/bash
# SONY αのSDカードから画像と動画をまとめて読み込むスクリプト
# 読込元: 以下のFROM変数にパスを設定してください。
# 読込先: このスクリプトが置かれている場所。
# 使い方
# このスクリプトとして保存してください。
# 「import」というファイルを作ります。(ファイルを作った場所に写真などが読み込まれます。)
# 「import」にこの内容を書き込み、ファイルに実行権限を与える。 (コマンド→ chmod 755 import)
# 42行目のパス部分をSDカードのパスに書き換えて保存してください。
# ダブルクリックなどで「import」を実行します。
# 動作説明
# このスクリプトが置かれているディレクトリに、日付ごとにフォルダを作成して画像と動画をコピーします。
# 画像の日付はSDカード内のフォルダ名を見て識別します。
#
# コピー元 例:
# /path/to/SDcard/DCIM/10740406/DSC01367.ARW
# /path/to/SDcard/DCIM/10740406/DSC01367.JPG
# /path/to/SDcard/private/M4ROOT/CLIP/20240406_C0051.MP4
# /path/to/SDcard/private/M4ROOT/CLIP/20240406_C0051M01.XML
#
# コピー先 例:
# ./(this script)
# ./20240406 107/C0051.MP4
# ./20240406 107/C0051M01.XML
# ./20240406 107/DSC01367.ARW
# ./20240406 107/DSC01367.JPG
#
# フォルダ名の日付を見て既存フォルダにコピーを試みます。
# フォルダ名の先頭の日付を維持していれば、フォルダの分割は自由です。新しいファイルは、名前順で最後のフォルダにコピーされます。
# 前提
# macOSで実行することを想定しています。linuxでは動作確認していません。
# αの設定
# 写真 フォルダー形式: 日付形式
# フォルダー名が、フォルダー番号+年月日(西暦下1桁月日4桁)になる。例:10030405(100フォルダー、2013年4月5日)
# 動画 ファイル名形式: 日付+タイトル
# ==========↓config↓==========
FROM="/Volumes/Untitled"
FROM=${FROM%/}
# ==========↑config↑==========
# ==========↓logic↓==========
SCRIPT_DIR=$(cd $(dirname "$0") && pwd)
cd "${SCRIPT_DIR}"
# ファイルを保存すべきフォルダの名前を標準出力に出力する。
#
# 第1引数に日付(保存先フォルダのprefixとしたい文字列)を取る。
# 第2引数に画像名(保存対象のファイル名)を取る。
#
# 日付から始まる名前で且つ、指定した画像を持つフォルダを探す。見つかれば名前順で先頭のフォルダの名前を標準出力に出力する。
# 見つからなければ日付から始まる名前のフォルダを探す。見つかれば名前順で最後のフォルダの名前を標準出力に出力する。
# それでも見つからなければ第1引数の文字列を標準出力に出力する。
#
# 検索はカレントディレクトリを起点とする。
#
# copyコマンドに指定するcopy先のパスを特定することが目的である。
# 名前が日付から始まるフォルダに写真/動画を保存すると仮定する。
# 基本機能は正しい日付から始まるフォルダ名を返すことである。
# 同じ日付で複数のフォルダを作れるようにしたい。日付の後に任意の文字列を追加することを想定する。
# SDカードから画像がcopy済みであればそのフォルダを特定したい。
# 同じ日付のフォルダが複数あれば、同一日に複数回取り込みが行われ、すでにフォルダ分割整理が行われていると考えられる。最も名前順で最後のフォルダが最新のフォルダであるとみなし、最新のフォルダを特定したい。
function find_copy_destination_folder () {
# 検索対象のフォルダのPrefix
START_WITH=$1
# 検索対象のフォルダが持つファイル (Optional)
SPECIFIC_FILE_NAME=$2
# SPECIFIC_FILEがいずれかのフォルダに存在するか確認
RES=$(find ./${START_WITH}* -name "${SPECIFIC_FILE_NAME}" 2>/dev/null)
if [ $? -ne 0 ]; then
# 予期せぬエラーの場合
:
elif [ -z "$RES" ]; then
# 存在しない場合
:
else
# 存在する場合
echo "$(echo "${RES%/*}" | sort | head -n 1)"
return
fi
# カレントディレクトリにてSTART_WITHから始まるフォルダを探索
RES=`find . -maxdepth 1 -type d -name "${START_WITH}*" 2>/dev/null`
if [ $? -ne 0 ]; then
# 予期せぬエラーの場合
echo "${START_WITH}"
elif [ -z "$RES" ]; then
# 存在しない場合
echo "${START_WITH}"
else
# 存在する場合
echo "$(echo "$RES" | sort | tail -n 1)"
fi
}
if [ ! -d ${FROM} ]; then
echo SDカードないで
exit 1
fi
echo 読込元: ${FROM}
# 読込元がαのSDカードかどうかを確認
# 以下のファイル/フォルダが存在していればαのSDカードであるとみなす。
\test -d ${FROM}/DCIM || { echo ${FROM}/DCIMがありません。SONY αのSDカードか確認してください; exit 1; }
\test -d ${FROM}/PRIVATE/DATABASE || { echo ${FROM}/PRIVATE/DATABASEがありません。SONY αのSDカードか確認してください; exit 1; }
\test -d ${FROM}/PRIVATE/M4ROOT || { echo ${FROM}/PRIVATE/M4ROOTがありません。SONY αのSDカードか確認してください; exit 1; }
\test -d ${FROM}/PRIVATE/M4ROOT/CLIP || { echo ${FROM}/PRIVATE/M4ROOT/CLIPがありません。SONY αのSDカードか確認してください; exit 1; }
\test -d ${FROM}/PRIVATE/SONY || { echo ${FROM}/PRIVATE/SONYがありません。SONY αのSDカードか確認してください; exit 1; }
\test -f ${FROM}/BODYDATA.DAT || { echo ${FROM}/BODYDATA.DATがありません。SONY αのSDカードか確認してください; exit 1; }
echo 出力先: ${SCRIPT_DIR}
# 写真
echo 写真をMacに取り込む
FROM_IMG="${FROM}/DCIM"
# SDカードの空フォルダを削除
find "${FROM_IMG}" -type d -empty -exec rmdir {} \; -prune
# 画像フォルダを処理する
for DIRNAME in $(ls "${FROM_IMG}");
do
# 画像フォルダ名から日付を解析する
# αでは画像のフォルダ名(DIRNAME)が、フォルダ番号(3桁)+年月日(西暦下1桁月日4桁)になっている。例:10010405(100フォルダ、2021年4月5日)
if [[ ! ${DIRNAME} =~ [0-9]{8} ]]; then continue; fi
dirpath="${FROM_IMG}/${DIRNAME}"
IMG_DATE=${DIRNAME:3} # 00405
YEAR=$(date "+%Y") # 今年の西暦
# 写真の日時がxxx9年で、今年がxxx9年ではない場合、多くの場合去年の写真であると推測されるので、YEARから10を引く
if [ ${IMG_DATE:0:1} = "9" ] && [ ! ${YEAR:3:1} = "9" ]; then YEAR=$((${YEAR} - 10)); fi
FOLDER_PREFIX="${YEAR:0:3}${IMG_DATE} ${DIRNAME:0:3}"
echo ${DIRNAME}フォルダの写真を取り込む
for FILENAME in $(ls "${dirpath}");
do
DIST_FOLDER_NAME=$(find_copy_destination_folder "${FOLDER_PREFIX}" "${FILENAME}")
mkdir -p "${DIST_FOLDER_NAME}"
# 実行内容表示 パーミッションと所有者とタイムスタンプを保持 上書きしない
cp -vpn "${dirpath}/${FILENAME}" "${DIST_FOLDER_NAME}"
done
done
# 動画
echo 動画を取り込む
FROM_MOV="${FROM}/private/M4ROOT/CLIP"
for FILENAME in $(ls ${FROM_MOV});
do
filepath="${FROM_MOV}/${FILENAME}"
# ファイル名が、日付+_+タイトル+ファイル番号になる。
MOV_DATE=${FILENAME%%_*}
MOV_TITLE=${FILENAME##*_}
DIST_FOLDER_NAME=$(find_copy_destination_folder "${MOV_DATE}" "${MOV_TITLE}")
mkdir -p "${DIST_FOLDER_NAME}"
# 実行内容表示 パーミッションと所有者とタイムスタンプを保持 上書きしない
cp -vpn "${filepath}" "${DIST_FOLDER_NAME}/${MOV_TITLE}"
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment