サイトのメンテナンスをしている時にたくさんの画像をリネームする時があります。ファイル名の頭にimgやphをつけたり、後ろに日付をつけたりと。これを手作業でやろうと思うと、とても大変です。キーボードだけで操作してF2キーを駆使しても、時間がかかります。これをバッチファイルで自動化してみましょう。
下記のバッチファイルを実行しますと、バッチファイルと同じディレクトリのファイルすべてに実行バッチファイル名が末尾に追記されます。つまり、ファイル名の末尾に追記したい文字をバッチファイル名にしておくということです。
@echo off
rem 実行バッチファイル名を取得
set add=%~n0
rem ファイル名の末尾に追記
for %%i in (*) do ren %%i %%~ni_%add%%%~xi
rem ファイル名の先頭に追記する場合
rem for %%i in (*) do ren %%i %add%_%%~ni%%~xi
pause
ファイル名の先頭に追記する場合は、コメントアウトしている部分を差し替えれば可能です。例として140401という日付を_(アンダーバー)でつなげて、後ろに追記する場合は、実行バッチファイル名を「_140401」とリネームしてから実行します。そうすると、同じディレクトリのすべてのファイル名の末尾に日付が追記されます。ただし、問題点として実行バッチファイル自身にも追記されてしまいます。
使い方と機能がわかったところで、少しソースの解説をしていきます。
まず最初に環境変数addに実行バッチファイル名を格納します。%0は実行バッチファイル名をフルパスで取得するので、そこに修飾指定子nをつけると(拡張子を含まない)ファイル名のみの取得となります。あとは、これをもとにfor文で一括リネームするだけです。
このソースでは環境変数の修飾指定子が重要ですので、一度下記で一覧をおさえておくと良いです。
Windows 2000 活用講座Windows 2000 コマンドライン徹底活用:第7回 forコマンド(その1) (1/3) - @IT
次は、さきほど実行バッチファイル名に文字が追記されてしまう問題点を改良してみましょう。
@echo off
rem 実行バッチファイル名を取得
set add=%~n0
for %%i in (*) do (
rem 実行バッチファイル自身以外に実行
if not %%i==%~n0%~x0 (
rem ファイル名の末尾に追記
ren %%i %%~ni_%add%%%~xi
)
)
pause
わかりやすいようにブロック文を使用しています。変更点はforの中で繰り返されるrenコマンドを実行バッチファイル以外で実行するようにしました。if文の条件式について解説します。環境変数iには次々とファイル名が差し替えられていきます。それを実行バッチファイル名と比較して、違う場合には処理を実行しています。%0で実行バッチファイルが取得できて、修飾指定子nでファイル名、xで拡張子を表します。これで、比較対象を作成しています。
これで何度でも同じ文字を追記できるようになりました。しかし、まだまだ改良点はあります。下記にリストアップしてみます。
- 文字の追記の場所を選択できない。
- 説明しないと、バッチファイル名が追記されることはわからない
この2つの解決にはバッチファイルが実行された時にすぐにリネーム作業に移るのではなく、追記場所の選択と、追記文字の入力を表示してから、リネームするようにしましょう。
@echo off
echo バッチファイルと同じディレクトのすべてのファイルをリネームします。
echo (拡張子を含まない)ファイル名のどの位置に文字を挿入しますか?
echo;
echo 0:先頭
echo 1:末尾
set /p select="数字で選択して下さい:"
set /p add="追記する文字を入力して下さい:"
if %select%==0 (
for %%i in (*) do (
rem 実行バッチファイル自身以外に実行
if not %%i==%~n0%~x0 (
rem 先頭に追記
ren %%i %add%%%~ni%%~xi
)
)
) else (
for %%i in (*) do (
rem 実行バッチファイル自身以外に実行
if not %%i==%~n0%~x0 (
rem 末尾に追記
ren %%i %%~ni%add%%%~xi
)
)
)
set /p
で文字の入力をさせることができます。それをもとに、何が選択されたかをif文で判定すれば良いです。ちなみにfor分なかでif文を書けば、if文は1つにまとまることができますが、今回はあえてforの外に出しています。理由はファイル数が100個あったとしたら、100回も先頭(0)、末尾(1)のどちらかが選択されたかを判定することになってしまいます。それを防ぐためにもif文はfor文の外に出して、はじめに選択を判定するようにしています。