付録: バッチ記法早見表

「書き方だけ確認したい」ときに引く一覧。解説は本編(第1〜3回)にあります

📅 作成: 2026-08-25 / 更新: 2026-08-25

目次

  1. 変数と展開
  2. 引数と %~ 修飾子
  3. エスケープ
  4. 条件分岐 if
  5. 繰り返し for
  6. 文字列操作
  7. リダイレクトと終了コード
  8. よく使うコマンド

変数と展開

代入

書き方意味備考
set VAR=値代入= の前後に空白を入れない。set VAR = 値 は変数名が VAR 、値が になる
set "VAR=値"代入(推奨形)値の末尾に空白が付かない。値に &| を含められる(ただし読み出しは !VAR! で行う。下の注意を参照)
set /a VAR=1+2数値計算して代入/a のときだけ値が数値として扱われる。% は剰余になる(バッチ内では %%
set /p VAR=入力: キーボード入力を代入入力待ちになる。無人実行するバッチでは使わない
set "VAR="変数を削除空文字の代入ではなく削除。if defined が偽になる

展開(読み出し)

書き方展開されるタイミング使う場面
%VAR%その行が読み込まれた時点(実行前)通常。ただし括弧ブロックの中では値が古いままになる。展開後の行がもう一度コマンドとして読み直される
!VAR!その行が実行される直前forif の括弧内。setlocal enabledelayedexpansion が必要。展開結果は読み直されないため記号を含む値でも安全
%%ffor の各回for のループ変数。バッチ内は %%、コマンドプロンプトに直接打つときは % 1つ

括弧の中では !VAR! を使う。forif() は、中に入る前に全体が1回だけ文字列展開されます。ループごとに変わる値を %VAR% で読むと、全周にわたって同じ値になります。

記号を含む値も !VAR! で読む。set "MSG=Hello & World" の代入は成功しますが、echo %MSG% は展開後の echo Hello & World という行が読み直され、& がコマンド区切りとして働いて壊れます。echo !MSG! なら展開結果が読み直されないため正しく表示されます。

スコープ

書き方意味
setlocalこれ以降の変数変更をこのスクリプト内に閉じる。書かないと呼び出し元の環境変数を書き換える
setlocal enabledelayedexpansion上に加えて !VAR! を有効にする。実質これが標準形
endlocal変更を破棄して元に戻す。スクリプト終了時に自動で行われる
endlocal & set "X=%X%"endlocal を越えて値を1つだけ持ち出す定型

引数と %~ 修飾子

引数の受け取り

書き方意味
%0実行されたバッチ自身のパス
%1%91〜9番目の引数
%*すべての引数をまとめた文字列
shift引数を1つずつずらす。10個以上の引数を扱うときに使う
%~11番目の引数から前後のダブルクォートを外したもの

%~ 修飾子(%0%1〜、for の変数に使える)

ここでは C:\work\data\input.txt が渡された場合の展開結果を示します。

書き方意味展開結果
%~1クォートを外すC:\work\data\input.txt
%~f1フルパスにするC:\work\data\input.txt
%~d1ドライブC:
%~p1パス部分\work\data\
%~dp1ドライブ+パスC:\work\data\
%~n1拡張子なしのファイル名input
%~x1拡張子.txt
%~nx1ファイル名+拡張子input.txt
%~s18.3形式の短いパス空白を含むパスの回避に使う
%~a1ファイル属性--a------
%~t1更新日時2026/08/25 10:30
%~z1ファイルサイズ1024

自分の場所を指す定型

書き方意味注意
%~dp0このバッチがあるフォルダ(末尾に \ 付き)"%~dp0file.txt" と連結する。"%~dp0\file.txt"\ が二重になる
%~nx0このバッチのファイル名使い方(usage)表示に使う
pushd "%~dp0"このバッチの場所へ移動UNC パスでも動く。戻すときは popd

エスケープ

文字そのまま書くとエスケープ備考
%変数展開として解釈される%%バッチファイル内のみ。プロンプトに直接打つときは % 1つ
^次の1文字のエスケープ記号^^行末に置くと行継続になる
&コマンドの区切り^&" で囲んだ中なら不要
|パイプ^|同上
> <リダイレクト^> ^<同上
( )ブロックの区切り^( ^)ブロック内では特に必要になる
!遅延展開が有効なとき変数として解釈される^^!^2つ必要。^! では展開されてしまう。遅延展開が無効ならエスケープ不要
"文字列の区切りエスケープできない。数を偶数に保つのが基本

迷ったら文字列全体を " で囲む。& | > < ( ) はダブルクォートの内側では特別扱いされません。^ を1文字ずつ付けるより事故が少なくなります。ただし %! はクォートの中でも展開されるため、これだけは %% / ^^! が必要です。

! だけ ^ が2つ必要な理由

1行は「% の展開 → ^ の処理 → ! の展開」という順に解釈されます。! の展開が ^ の処理よりにあるため、^! と書くと ^ が先に消費されて ! だけが残り、そのあと変数として展開されてしまいます。

@echo off
setlocal enabledelayedexpansion
set "MSG=VALUE"
echo 1: ^!MSG^!
echo 2: ^^!MSG^^!
1: VALUE
2: !MSG!

^^^ 1つに減り、その ^! の展開を止めます。! をリテラルで出したいだけなら、その箇所を setlocal disabledelayedexpansion で囲んで遅延展開を切るほうが読みやすくなります。

行継続

rem 長いコマンドを複数行に分ける(行末に ^ 、次の行は続きとして扱われる)
robocopy "C:\src" "C:\dst" ^
    /E /R:1 /W:1 ^
    /LOG:"%~dp0robocopy.log"

要注意^ の後ろに空白があると行継続として機能しません。行末は ^ で終わらせます。

条件分岐 if

基本形

書き方意味
if "%A%"=="x" ( … )文字列の一致。両辺を " で囲むのが定型(空のときに構文エラーになるのを防ぐ)
if /i "%A%"=="x" ( … )大文字小文字を区別しない比較
if not "%A%"=="x" ( … )否定
if defined A ( … )変数が定義されているか。% で囲まない
if exist "path" ( … )ファイル・フォルダの存在。フォルダを確かめたいときは "path\" と末尾に \ を付ける
if errorlevel 1 ( … )直前の終了コードが 1以上なら真(「1と等しい」ではない)
if %N% GEQ 10 ( … )数値比較

数値比較の演算子

演算子意味他言語
EQU等しい==
NEQ等しくない!=
LSSより小さい<
LEQ以下<=
GTRより大きい>
GEQ以上>=

else の書き方

rem 正しい: ) と else と ( を同じ行に置く
if "%A%"=="x" (
    echo A は x
) else (
    echo A は x ではない
)

構文エラー)else を別の行に分けると動きません。if は1つの論理行として解析されるためです。

if の中で %errorlevel% は使えない。ブロック内の %errorlevel% はブロックに入る前の値に固定されています。ブロック内で更新後の値を見るには !errorlevel!if errorlevel 1 を使います。

繰り返し for

4つの形

回すもの
無印ファイル名・空白区切りの文字列for %%f in (*.txt) do echo %%f
/l数値の範囲(開始,増分,終了)for /l %%i in (1,1,5) do echo %%i
/fファイルの各行・文字列・コマンド出力for /f "delims=" %%l in (a.txt) do echo %%l
/rサブフォルダを含むファイルfor /r "C:\work" %%f in (*.log) do echo %%f
/dフォルダのみfor /d %%d in (*) do echo %%d

/f のオプション

オプション意味
delims=,区切り文字を指定(既定は空白とタブ)。delims= と空にすると行全体を1つとして扱う
tokens=1,3取り出す列の番号。tokens=1,* で「1列目」と「残り全部」
skip=1先頭のn行を飛ばす(ヘッダ行の読み飛ばし)
eol=;この文字で始まる行を無視する(既定は ;
usebackq引用符の意味を変える。空白を含むファイル名を読むときに必要

対象の指定と引用符

書き方回す対象
in (a.txt)ファイル a.txt の各行
in ("文字列")その文字列そのもの(ファイルではない)
in ('コマンド')コマンドの実行結果の各行
in ("C:\a b\c.txt")usebackq空白を含むパスのファイルの各行
rem 空白を含むパスのファイルを1行ずつ読む
for /f "usebackq delims=" %%l in ("%~dp0data file.txt") do (
    echo 行: %%l
)

rem コマンドの出力を読む(usebackq のときはバッククォート)
for /f "usebackq tokens=1,2 delims=," %%a in (`type list.csv`) do (
    echo 1列目=%%a 2列目=%%b
)

tokens を複数指定すると変数は自動で増える。tokens=1,2,3%%a を指定した場合、2列目は %%b、3列目は %%c になります。宣言は不要で、アルファベット順に割り当てられます。

ループの脱出

break はありません。goto でループの外のラベルへ飛ぶか、フラグ変数で以降の処理をスキップします。

for %%f in (*.txt) do (
    if "%%~nf"=="target" goto :found
)
echo 見つかりませんでした
goto :eof

:found
echo 見つかりました

文字列操作

いずれも %VAR% 形式の変数にしか使えません。引数 %1for%%f に直接は使えないため、いったん set "V=%~1" で変数に入れます。

書き方意味例(V=abcdefg
%V:~0,3%0文字目から3文字abc
%V:~3%3文字目から末尾までdefg
%V:~-2%末尾から2文字fg
%V:~0,-2%末尾2文字を除いた残りabcde
%V:abc=X%置換Xdefg
%V:abc=%削除(空文字に置換)defg

よく使う組み合わせ

やりたいこと書き方
文字列を含むか判定if not "%V:abc=%"=="%V%" ( 含む )
末尾の \ を取り除くif "%V:~-1%"=="\" set "V=%V:~0,-1%"
パスの区切りを置換set "V=%V:\=/%"
大文字小文字を無視して置換不可。for /f と外部コマンドを使う

置換・部分取得は !V! 形式でも書ける。ループ内で使う場合は !V:~0,3! のように ! で囲みます。ただし値そのものに =: が含まれると解釈が崩れるため、この記法で扱うのはパスや識別子程度にとどめるのが安全です。

リダイレクトと終了コード

リダイレクト

書き方意味
> file標準出力をファイルへ(上書き)
>> file標準出力をファイルへ(追記)
2> file標準エラーをファイルへ
> file 2>&1標準出力と標準エラーをまとめてファイルへ
> nul出力を破棄する
2> nulエラー出力だけ破棄する
< fileファイルを標準入力として渡す
cmd1 | cmd2cmd1 の出力を cmd2 の入力へ

要注意2>&1 は「その時点の標準出力と同じ先」を意味するため、順序が変わると結果が変わります。> file 2>&1 は両方がファイルへ、2>&1 > file は標準出力だけがファイルへ行き、エラーは画面に残ります。

終了コード

書き方意味
%errorlevel%直前のコマンドの終了コード。0 が成功
if errorlevel 11以上(=失敗)なら真
cmd && 次cmd が成功したときだけ次を実行
cmd || 次cmd が失敗したときだけ次を実行
exit /b nこのバッチを終了コード n で終える
exit ncmd.exe そのものを終える(呼び出し元も閉じる)
goto :eofサブルーチンから戻る / スクリプトの末尾へ飛ぶ
rem 失敗したら中断する定型
copy "%SRC%" "%DST%" || (
    echo コピーに失敗しました
    exit /b 1
)

サブルーチン

call :log "処理を開始します"
call :log "処理が完了しました"
goto :eof

:log
echo [%DATE% %TIME%] %~1
goto :eof

call を付けずに :loggoto すると、そこから戻ってきません。

よく使うコマンド

ファイル・フォルダ

コマンド用途覚えておくオプション
copyファイルのコピー/y 上書き確認なし
xcopyフォルダごとコピー/e /i /y
robocopy大量・差分コピー/e /r:1 /w:1。終了コードが 0 以外でも成功のことがある
move移動・リネーム/y
delファイル削除/q 確認なし /s サブフォルダも
rdフォルダ削除/s /q
mdフォルダ作成途中の階層も自動で作られる
dir一覧/b 名前だけ /s 再帰 /a-d ファイルのみ

テキスト・情報取得

コマンド用途備考
typeファイルの内容を表示複数ファイルの連結にも使える
find文字列の検索" で囲む必要がある。/c で件数、/v で否定
findstr正規表現の検索/i 大小無視 /r 正規表現 /c:"..." 語句指定
where実行ファイルの場所を探す存在確認にも使える(見つからないと終了コードが 1)
tasklistプロセス一覧/fi "imagename eq x.exe"
chcpコードページの確認・変更日本語環境は 93265001(UTF-8)への変更は副作用があるため安易に使わない

制御・その他

コマンド用途備考
@echo off実行するコマンド自体の表示を止める1行目に書く。先頭の @ はこの行自身を隠すため
remコメント括弧の中でも安全。:: はラベルなので括弧内では使えない
pauseキー入力を待つダブルクリック実行で結果を読ませたいときに末尾へ
timeout /t 55秒待つ/nobreak でキー入力による中断を防ぐ
start ""別プロセスとして起動第1引数はウィンドウタイトル扱いなので "" を置く
call other.cmd別のバッチを呼んで戻るcall なしでは戻ってこない
pushd / popd移動して戻るUNC パスにも対応する
titleウィンドウタイトルを設定長時間動くバッチで進捗を示すのに使える

コマンドのヘルプは コマンド /? で読める。for /?set /? は、この早見表より詳しい説明を出します。出力が長いので for /? | more やファイルへのリダイレクトと併せて使ってください。