「100枚の画像ファイル全部に new_ を付けたい」「納品前に全ファイルを _v2 に変えたい」──手作業では数分かかる一括リネームも、バッチファイルなら数秒で完了します。
この記事では for・ren・遅延展開 を組み合わせた先頭/末尾への文字一括追加を、ドライラン・再帰処理・拡張子絞り込み・日付自動付与まで段階的に解説します。
目次
- 基本形:先頭・末尾に固定文字を追加
- ドライラン(確認専用)モード
- 特定拡張子のみ対象にする
- サブフォルダを再帰処理する
- 日付・連番を自動付与する
- 落とし穴5選
- 実践例3本
- よくある質問(FAQ)
- まとめ
基本形:先頭・末尾に固定文字を追加
バッチファイルによるリネームは ren(rename)コマンド と for ループ、そして 遅延展開(setlocal enabledelayedexpansion) の3要素で成り立っています。
先頭に文字を追加する
@echo off
setlocal enabledelayedexpansion
set "TARGET_DIR=C:\work\files" :: 対象フォルダのパス
set "PREFIX=new_" :: 先頭に追加する文字列
pushd "%TARGET_DIR%"
for %%F in (*) do (
set "FNAME=%%~nxF"
ren "%%F" "!PREFIX!!FNAME!"
)
popd
endlocal
echo 完了
ポイント:%%~nxF で「ファイル名+拡張子」をまとめて取得し、その前に !PREFIX! を連結しています。! を使う遅延展開が必須なのはループ内で変数を参照するためです。
末尾に文字を追加する
末尾追加では 拡張子を分離 して「名前部分+追加文字+拡張子」に組み立て直します。
@echo off
setlocal enabledelayedexpansion
set "TARGET_DIR=C:\work\files"
set "SUFFIX=_v2" :: 末尾に追加する文字列
pushd "%TARGET_DIR%"
for %%F in (*) do (
set "BASENAME=%%~nF" :: 拡張子なしのファイル名
set "EXT=%%~xF" :: .txt .jpg 等の拡張子
ren "%%F" "!BASENAME!!SUFFIX!!EXT!"
)
popd
endlocal
echo 完了
%%~nF(名前のみ)と %%~xF(拡張子のみ)を組み合わせることで、report_v2.txt のように拡張子の直前に挿入できます。
先頭・末尾を同時に追加する
@echo off
setlocal enabledelayedexpansion
set "TARGET_DIR=C:\work\files"
set "PREFIX=2024_"
set "SUFFIX=_final"
pushd "%TARGET_DIR%"
for %%F in (*) do (
set "BASENAME=%%~nF"
set "EXT=%%~xF"
ren "%%F" "!PREFIX!!BASENAME!!SUFFIX!!EXT!"
)
popd
endlocal
echo 完了
ドライラン(確認専用)モード
実際にリネームする前に 変更後のファイル名を画面で確認 できるドライランは、ミスを防ぐ必須ステップです。
@echo off
setlocal enabledelayedexpansion
set "TARGET_DIR=C:\work\files"
set "PREFIX=new_"
set "SUFFIX=_v2"
set "DRYRUN=1" :: 0 にすると実際に変更する
pushd "%TARGET_DIR%"
for %%F in (*) do (
set "BASENAME=%%~nF"
set "EXT=%%~xF"
set "NEWNAME=!PREFIX!!BASENAME!!SUFFIX!!EXT!"
if "!DRYRUN!"=="1" (
echo [DRY] "%%F" --> "!NEWNAME!"
) else (
ren "%%F" "!NEWNAME!"
echo [DONE] "%%F" --> "!NEWNAME!"
)
)
popd
endlocal
DRYRUN=1 のときは echo のみ実行し、0 に変更したときだけ実際にリネームします。大量のファイルに適用する前に必ずドライランで確認しましょう。
特定拡張子のみ対象にする
フォルダ内に複数種類のファイルが混在している場合は、for %%F in (*.txt) のようにワイルドカードで絞り込めます。
@echo off
setlocal enabledelayedexpansion
set "TARGET_DIR=C:\work\files"
set "PREFIX=draft_"
set "EXT_FILTER=*.txt" :: 対象拡張子(*.jpg, *.csv なども可)
pushd "%TARGET_DIR%"
for %%F in (%EXT_FILTER%) do (
set "FNAME=%%~nxF"
ren "%%F" "!PREFIX!!FNAME!"
)
popd
endlocal
echo 完了
複数拡張子 を対象にしたい場合は for %%F in (*.txt *.csv *.log) のようにスペース区切りで並べます。
サブフォルダを再帰処理する
フォルダ配下のすべてのサブフォルダも含めて処理したい場合は for /r を使います。
@echo off
setlocal enabledelayedexpansion
set "TARGET_DIR=C:\work\files"
set "PREFIX=bak_"
:: /r でサブフォルダも再帰的に処理
for /r "%TARGET_DIR%" %%F in (*) do (
set "DIRPATH=%%~dpF"
set "FNAME=%%~nxF"
ren "%%F" "!PREFIX!!FNAME!"
)
endlocal
echo 完了
注意:再帰処理では既にリネームされたファイルが再度対象になる場合があります(例:bak_ を付けたファイルがさらに bak_bak_ になるケース)。先にドライランで確認し、重複防止チェックを入れることを推奨します。
重複防止チェック付き再帰版
@echo off
setlocal enabledelayedexpansion
set "TARGET_DIR=C:\work\files"
set "PREFIX=bak_"
for /r "%TARGET_DIR%" %%F in (*) do (
set "FNAME=%%~nxF"
:: すでに PREFIX が付いていたらスキップ
if "!FNAME:~0,4!" NEQ "!PREFIX!" (
ren "%%F" "!PREFIX!!FNAME!"
echo [DONE] %%F
) else (
echo [SKIP] %%F
)
)
endlocal
echo 完了
!FNAME:~0,4! は文字列の先頭4文字を取り出す構文です。PREFIX の文字数に合わせて数値を変更してください(bak_ は4文字なので ~0,4)。
日付・連番を自動付与する
今日の日付を先頭に追加する
@echo off
setlocal enabledelayedexpansion
set "TARGET_DIR=C:\work\files"
:: 日付を YYYYMMDD 形式に整形(例:20241025)
for /f "tokens=1-3 delims=/-" %%a in ("%DATE%") do (
set "YYYY=%%a"
set "MM=%%b"
set "DD=%%c"
)
set "TODAY=%YYYY%%MM%%DD%"
pushd "%TARGET_DIR%"
for %%F in (*) do (
set "FNAME=%%~nxF"
ren "%%F" "!TODAY!_!FNAME!"
)
popd
endlocal
echo 完了(日付: %TODAY%)
日付の整形パターンや %DATE% 変数の詳細については「【bat】日付と時間をファイル名に挿入する方法完全ガイド」も参照してください。
連番を先頭に追加する
@echo off
setlocal enabledelayedexpansion
set "TARGET_DIR=C:\work\files"
set /a COUNT=1
pushd "%TARGET_DIR%"
for %%F in (*) do (
set "FNAME=%%~nxF"
:: 3桁ゼロ埋め(001, 002, ...)
set "NUM=00!COUNT!"
set "NUM=!NUM:~-3!"
ren "%%F" "!NUM!_!FNAME!"
set /a COUNT+=1
)
popd
endlocal
echo 完了
set "NUM=00!COUNT!" で 001・002… と3桁ゼロ埋めしています。!NUM:~-3! は右から3文字を取り出す構文です。
落とし穴5選
落とし穴1:遅延展開を有効にしていない
for ループ内で set した変数をループ内で参照するには、setlocal enabledelayedexpansion と ! 記法が必須です。% 記法はループに入る前に1回だけ展開されるため、ループ内で set した値は反映されません。
:: NG:%FNAME% はループ内の set の前に展開されるため、前回の値(または空)になる
for %%F in (*) do (
set "FNAME=%%~nF"
ren "%%F" "%PREFIX%_%FNAME%%%~xF" :: %FNAME% は空のまま!
)
:: OK:setlocal enabledelayedexpansion + ! 記法を使う
setlocal enabledelayedexpansion
for %%F in (*) do (
set "FNAME=%%~nF"
ren "%%F" "!PREFIX!_!FNAME!%%~xF" :: !FNAME! はループ内の set の値が使われる
)
落とし穴2:ファイル名にスペースが含まれる
ファイル名や変数にスペースが入っている場合、ダブルクォートで囲まないと誤動作します。ren "%%F" "!NEWNAME!" のように 両方をクォートで囲む のが鉄則です。
:: NG:スペース入りのファイル名が分割される ren %%F !PREFIX!!FNAME! :: OK:両方をダブルクォートで囲む ren "%%F" "!PREFIX!!FNAME!"
落とし穴3:フォルダもリネームされる
for %%F in (*) は通常ファイルのみを対象にしますが、for /r 再帰版ではサブフォルダ自体がヒットする場合があります。フォルダを除外するには属性チェックを加えます。
for /r "%TARGET_DIR%" %%F in (*) do (
:: フォルダは除外(属性にdが含まれていたらスキップ)
if exist "%%F" if not exist "%%F\" (
set "FNAME=%%~nxF"
ren "%%F" "!PREFIX!!FNAME!"
)
)
落とし穴4:日本語ファイル名が文字化けする
バッチファイルのデフォルト文字コードはShift-JIS(CP932)です。UTF-8のファイル名を扱う場合や他の環境で作成したファイルは文字化けすることがあります。詳細は「【bat】日本語ファイル名を扱うときの注意点と解決策」を参照してください。
落とし穴5:拡張子なしのファイルで末尾追加が崩れる
%%~xF は拡張子がないファイルでは空文字を返します。通常は問題ありませんが、追加文字に . が含まれる場合(例:_v2.0)は意図しない拡張子が付いてしまうことがあるため注意が必要です。
実践例3本
実践例1:納品ファイルに会社略称を一括追加
納品時に ABC_(会社名略称)+日付を先頭に自動付与するスクリプトです。
@echo off
setlocal enabledelayedexpansion
set "TARGET_DIR=C:\work\deliverables"
set "COMPANY=ABC"
:: 今日の日付を YYYYMMDD で取得
for /f "tokens=1-3 delims=/-" %%a in ("%DATE%") do (
set "YYYY=%%a"
set "MM=%%b"
set "DD=%%c"
)
set "TODAY=%YYYY%%MM%%DD%"
set "PREFIX=%COMPANY%_%TODAY%_"
echo 以下のファイルをリネームします:
pushd "%TARGET_DIR%"
:: ドライラン確認
for %%F in (*) do (
set "FNAME=%%~nxF"
echo "%%F" --> "!PREFIX!!FNAME!"
)
echo.
set /p CONFIRM=実行しますか?(y/n):
if /i "!CONFIRM!" NEQ "y" (
echo キャンセルしました
popd & endlocal & exit /b
)
:: 実際にリネーム
for %%F in (*) do (
set "FNAME=%%~nxF"
ren "%%F" "!PREFIX!!FNAME!"
)
popd
endlocal
echo 完了
実践例2:バージョン管理用サフィックス追加
作業中のCSVファイルに _bak を末尾に付けてバックアップコピーを作成するスクリプトです。コピーを作ってからリネームするため元ファイルは残ります。
@echo off
setlocal enabledelayedexpansion
set "TARGET_DIR=C:\work\data"
set "SUFFIX=_bak"
pushd "%TARGET_DIR%"
for %%F in (*.csv) do (
set "BASENAME=%%~nF"
set "EXT=%%~xF"
:: copy でバックアップを作ってからリネーム先に保存
copy "%%F" "!BASENAME!!SUFFIX!!EXT!" > nul
echo [BAK] "%%F" --> "!BASENAME!!SUFFIX!!EXT!"
)
popd
endlocal
echo バックアップ完了
実践例3:画像ファイルにプロジェクトIDとシーケンス番号を付与
プロジェクトIDと3桁連番を先頭に付けて画像ファイルを整理します。IMG_001.jpg・IMG_002.jpg のような形式に統一できます。
@echo off
setlocal enabledelayedexpansion
set "TARGET_DIR=C:\work\images"
set "PROJECT_ID=PROJ01"
set /a SEQ=1
pushd "%TARGET_DIR%"
for %%F in (*.jpg *.png *.bmp) do (
set "EXT=%%~xF"
:: 3桁ゼロ埋め
set "NUM=00!SEQ!"
set "NUM=!NUM:~-3!"
set "NEWNAME=%PROJECT_ID%_IMG_!NUM!!EXT!"
ren "%%F" "!NEWNAME!"
echo [DONE] "%%F" --> "!NEWNAME!"
set /a SEQ+=1
)
popd
endlocal
echo 完了
%PROJECT_ID% はループ外で設定した変数なので % 記法で参照しています。ループ内で set した NUM・EXT は ! 記法で参照しています。
よくある質問(FAQ)
if "!FNAME:~0,N!" NEQ "!PREFIX!"(Nはprefixの文字数)でチェックしてスキップする処理を入れてください。上記「重複防止チェック付き再帰版」を参考にしてください。!BASENAME:~0,N!(前半)と !BASENAME:~N!(後半)で文字列を分割してから挿入文字を間に挟みます。または「ファイル名の特定の文字列を置換するバッチファイル」のように文字列置換を利用する方法もあります。for /d %%F in (*) を使います。%%~nF でフォルダ名を取得できます。ただし for /d では拡張子は存在しないため %%~xF は不要です。Rename-Item パイプラインが高速です。バッチファイルの観点では for /f "usebackq" + dir /b を組み合わせることで若干改善できる場合があります。ren *.txt *.bak のシンプルなパターンから再帰処理まで解説しています。まとめ
バッチファイルでファイル名の先頭・末尾に文字を一括追加するポイントをまとめます。
- 先頭追加:
%%~nxF(名前+拡張子)の前に PREFIX を連結するだけ - 末尾追加:
%%~nF(名前のみ)+ SUFFIX +%%~xF(拡張子)で組み立て - 遅延展開:
setlocal enabledelayedexpansionと!記法は for ループ内で必須 - ドライラン:
DRYRUN=1フラグで変更前に必ず確認 - サブフォルダ再帰:
for /r+ 重複防止チェックを組み合わせる - スペース・日本語:常にダブルクォートで囲む
関連記事もあわせてご覧ください。