Created
April 4, 2025 11:24
-
-
Save fujimogn/435710a2b479434047fa3a49556dab03 to your computer and use it in GitHub Desktop.
ファイル自動でリネームするworkflow(クイックアクション)用スクリプト
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/zsh | |
set -e | |
export PATH="/usr/local/bin:/opt/homebrew/bin:$PATH" | |
############################################################################### | |
# 必要な Brew インストールライブラリ: | |
# - poppler: brew install poppler | |
# - tesseract: brew install tesseract | |
# - csvkit: brew install csvkit | |
# - jq: brew install jq | |
# - docx2txt: brew install docx2txt | |
# - xlsx2csv: brew install xlsx2csv | |
# - base64: macOS 標準搭載 | |
# - file: macOS 標準搭載 | |
############################################################################### | |
# APIキー | |
API_KEY="" | |
# 定数設定 | |
MODEL="gpt-4o" | |
TEMPERATURE=0.7 | |
HEAD_CHAR_LIMIT=1000 | |
function encode_file_to_base64() { | |
local file="$1" | |
base64 -i "$file" | tr -d '\n' | |
} | |
function get_mime_type() { | |
local file="$1" | |
file --mime-type -b "$file" | |
} | |
function get_file_content() { | |
local file="$1" | |
local ext content | |
ext="${file##*.}" | |
ext=$(echo "$ext" | tr '[:upper:]' '[:lower:]') | |
if [[ "$ext" == "pdf" ]]; then | |
command -v pdftotext >/dev/null 2>&1 || { echo "エラー: pdftotext が必要です。" >&2; return 1; } | |
content=$(pdftotext "$file" - 2>/dev/null | head -c "$HEAD_CHAR_LIMIT") | |
elif [[ "$ext" =~ ^(jpg|jpeg|png|bmp|gif|tiff)$ ]]; then | |
# 画像は対象外(空文字返す) | |
content="" | |
elif [[ "$ext" == "docx" ]]; then | |
if command -v docx2txt >/dev/null 2>&1; then | |
content=$(docx2txt "$file" - 2>/dev/null | head -c "$HEAD_CHAR_LIMIT") | |
elif command -v textutil >/dev/null 2>&1; then | |
content=$(textutil -convert txt -stdout "$file" 2>/dev/null | head -c "$HEAD_CHAR_LIMIT") | |
else | |
echo "エラー: docx2txt または textutil が必要です。" >&2 | |
return 1 | |
fi | |
elif [[ "$ext" == "doc" ]]; then | |
command -v textutil >/dev/null 2>&1 || { echo "エラー: textutil が必要です。" >&2; return 1; } | |
content=$(textutil -convert txt -stdout "$file" 2>/dev/null | head -c "$HEAD_CHAR_LIMIT") | |
elif [[ "$ext" == "xlsx" ]]; then | |
if command -v xlsx2csv >/dev/null 2>&1; then | |
content=$(xlsx2csv "$file" 2>/dev/null | head -c "$HEAD_CHAR_LIMIT") | |
elif command -v in2csv >/dev/null 2>&1; then | |
content=$(in2csv "$file" 2>/dev/null | head -c "$HEAD_CHAR_LIMIT") | |
else | |
echo "エラー: xlsx2csv または in2csv が必要です。" >&2 | |
return 1 | |
fi | |
elif [[ "$ext" == "xls" ]]; then | |
command -v in2csv >/dev/null 2>&1 || { echo "エラー: in2csv が必要です。" >&2; return 1; } | |
content=$(in2csv "$file" 2>/dev/null | head -c "$HEAD_CHAR_LIMIT") | |
else | |
content=$(head -c "$HEAD_CHAR_LIMIT" "$file") | |
fi | |
echo "$content" | |
} | |
function get_new_filename() { | |
local original_name="$1" | |
local file_content="$2" | |
local file_date="$3" | |
local is_image="$4" | |
local base64_data="$5" | |
local mime_type="$6" | |
local prompt response new_name tmp_payload tmp_base64 | |
prompt=$(cat <<'EOF' | |
# 命令 | |
以下のファイル情報をもとに、内容に合った適切な新しいファイル名を提案してください。 | |
**必ず** "YYYY-MM-DD_ファイルの名前" の形式で、ファイル名のみを1行で出力してください。 | |
もし適切なファイル名が提案できない場合は、元のファイル名をそのまま返してください。 | |
# 出力形式 | |
{YYYY-MM-DD}_{ファイル名} | |
# 出力例 | |
2025-01-01_アカウント請求書 | |
# ルール | |
・{YYYY-MM-DD} はファイル内に記載の日付、なければファイル作成日を使用してください。 | |
・ファイル名は簡潔に、日本語でわかりやすく命名してください。 | |
・拡張子は不要です(こちらで追加します)。 | |
EOF | |
) | |
tmp_payload=$(mktemp /tmp/chatgpt_payload.XXXXXX.json) | |
if [[ "$is_image" == "true" ]]; then | |
tmp_base64=$(mktemp /tmp/base64_data.XXXXXX.txt) | |
echo "$base64_data" > "$tmp_base64" | |
jq -n \ | |
--arg model "$MODEL" \ | |
--arg text_prompt "$prompt\n\n# 元のファイル名\n$original_name\n\n# ファイル作成日\n$file_date" \ | |
--arg mime "$mime_type" \ | |
--rawfile image_data "$tmp_base64" \ | |
'{ | |
model: $model, | |
messages: [{ | |
role: "user", | |
content: [ | |
{ "type": "text", "text": $text_prompt }, | |
{ "type": "image_url", "image_url": { "url": ("data:" + $mime + ";base64," + $image_data) } } | |
] | |
}], | |
temperature: 0.7 | |
}' > "$tmp_payload" | |
rm -f "$tmp_base64" | |
else | |
prompt=$(printf "%s\n\n# 元のファイル名\n%s\n\n# ファイル作成日\n%s\n\n# ファイルの内容(先頭部分)\n%s" \ | |
"$prompt" "$original_name" "$file_date" "$file_content") | |
jq -n \ | |
--arg model "$MODEL" \ | |
--arg content "$prompt" \ | |
'{ | |
model: $model, | |
messages: [{ role: "user", content: $content }], | |
temperature: 0.7 | |
}' > "$tmp_payload" | |
fi | |
response=$(curl -s "https://api.openai.com/v1/chat/completions" \ | |
-H "Content-Type: application/json" \ | |
-H "Authorization: Bearer ${API_KEY}" \ | |
-d @"$tmp_payload") | |
rm -f "$tmp_payload" | |
if echo "$response" | grep -q "\"error\":"; then | |
echo "APIエラーが発生しました:$response" >&2 | |
return 1 | |
fi | |
new_name=$(echo "$response" | jq -r '.choices[0].message.content' | tr -d '\n\r' | sed 's/[\/:*?"<>|]/_/g' | sed 's/ */ /g') | |
echo "$new_name" | |
} | |
for file in "$@"; do | |
if [[ ! -e "$file" ]]; then | |
echo "エラー: ファイル '$file' は存在しません。" >&2 | |
continue | |
fi | |
original_name=$(basename "$file") | |
extension="${original_name##*.}" | |
extension=$(echo "$extension" | tr '[:upper:]' '[:lower:]') | |
file_creation_date=$(stat -f "%SB" -t "%Y-%m-%d" "$file") | |
mime_type=$(get_mime_type "$file") | |
if [[ "$mime_type" =~ ^image/ ]]; then | |
is_image="true" | |
base64_data=$(encode_file_to_base64 "$file") | |
file_content="" | |
else | |
is_image="false" | |
base64_data="" | |
file_content=$(get_file_content "$file") | |
fi | |
new_name=$(get_new_filename "$original_name" "$file_content" "$file_creation_date" "$is_image" "$base64_data" "$mime_type") || { | |
echo "ファイル「${original_name}」のリネームに失敗しました。" >&2 | |
continue | |
} | |
new_name="${new_name}.${extension}" | |
if [[ "$new_name" == "$original_name" ]]; then | |
echo "新しいファイル名が元のファイル名と同じため、リネームは行いません。" | |
continue | |
fi | |
dir=$(dirname "$file") | |
new_path="${dir}/${new_name}" | |
mv "$file" "$new_path" | |
echo "「${original_name}」→「${new_name}」にリネームしました。" | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment