複数ファイル・フォルダ内のファイルを一括処理するバッチの書き方(for~in~do)【mozjpeg】
難しいことを考えずに、フォルダ、または複数ファイルを直接ドラッグアンドドロップで処理を渡せる Windows バッチファイルの作り方です。
パスに空白が入っていてもOKです。
このバッチファイルにフォルダをドラッグ・アンド・ドロップした場合は、フォルダ内に含まれる全ファイルをそれぞれ、また、複数ファイルを直接ドラッグ・アンド・ドロップした場合は各ファイルについて順次処理します。
複数ファイルやフォルダ単位での処理に対応していないプログラムに一括処理させるのに便利な方法です。
空白のための特殊な処理はしておらず、適切なところで””(ダブルクォート)で囲んでいるだけです。
フォルダ、または複数ファイルを一括処理するバッチファイルの例
ここでは、ある変換プログラム「jpeg-static.exe」を例に、<infile> に複数ファイルを喰わせるバッチ処理(.batファイル)を書きます。
参考までに変換プログラム「jpeg-static.exe」の使い方は以下の通り。
jpeg-static.exe <other_options> -outfile <outfile> <infile>
バッチファイルと jpeg-static.exe は同じディレクトリにあるものとします。
このバッチで処理できるのは、1つのフォルダ、または単一ファイル、または複数ファイルです。複数フォルダの処理や、フォルダを再帰的に掘る処理はできません。
@echo off if exist "%1\*" ( cd /d "%1" mkdir "shrinked" > nul 2>&1 for %%q in (*) do ( echo %%q "%~dp0cjpeg-static.exe" -optimize -quality 75 -outfile "shrinked\%%q" "%%q" ) ) else if exist "%1" ( cd /d "%~dp0" mkdir "%~dp1shrinked\" > nul 2>&1 for %%q in (%*) do ( echo %%q "%~dp0cjpeg-static.exe" -optimize -quality 75 -outfile "%%~dpqshrinked\%%~nxq" "%%q" ) )
上記の例では、ドラッグアンドドロップした場所に「shrinked」フォルダを作成し、その中に結果を出力します。
やってることは「mozjpeg で JPG 画像ファイルを一括縮小するバッチファイル」というだけですね。
なお、このバッチファイルをネットワーク越しに直接叩く場合は、ネットワークドライブの設定が必要です。
バッチファイル中の特殊な表記の解説
特殊ってわけでもありませんが、Windows のバッチファイルは、若干ロストテクノロジー化してる気がするので解説。
- 「%*」は全引数を含む文字列。
引数が複数の場合、「”D:\foo\bar 1.jpg” “D:\foo\bar 2.jpg”」みたくダブルクォートで括って、かつスペースで分離した形式になる - 「%%q」はforループ中の一時変数「q」
例で言うと、1回目=”D:\foo\bar 1.jpg”、2回目=”D:\foo\bar 2.jpg” - 「%%~dpq」はforループ中の一時変数「q」のうち、ドライブレター部分+パス部分を連結した文字列
例で言うと、1回目=”D:\foo\”、2回目=”D:\foo\” - 「%%~nxq」はforループ中の一時変数「q」のうち、ファイル名+拡張子を連結した文字列
例で言うと、1回目=”bar 1.jpg”、2回目=”bar 2.jpg” - 「%~dp0」はバッチファイルがある場所のドライブ名付きフルパス
ざっくりと言えばこんな感じです。
今なら Windows PowerShell を使う方が良さそうですが、自分用ならこんな手もありますよ、と。
環境によっては実行時に警告が出ますので、各自、適切に処理してください。
ちなみに僕はこの手のロストテクノロジー的なスクリプティングは好みませんが、生産性視点から必要があれば読み書きくらいはする方針です。
※ 2022/7/19 「複数ファイルを一括処理するバッチファイルの書き方」として公開していた記事を、フォルダ丸ごとの処理にも対応できるよう追記。新記事扱い。
GG says:
7年前
違うソフトでバッチファイルの作成をしようと思ったのですがうまく動かず、検索してこちらの記事を拝見しました。
こちらの記事のおかげで問題なく動くバッチファイルが出来ました。
特に、説明をも付け加えていただいていて、自分のような知識のないものにとってとてもありがたかったです。