Last active
June 28, 2025 10:50
-
-
Save on0z/8ef511d808d1a1b790d89a9010250062 to your computer and use it in GitHub Desktop.
importFromSonyAlpha ソニー製カメラαから,写真と動画を整理して取り出すスクリプト
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
#!/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