Skip to content
nishi_74322014 edited this page Aug 3, 2026 · 1 revision

BAT

概要

UNIX系OSのシェル・スクリプトに相当する。

詳細

以下のようなトピック情報を纏めています。

  • batファイルの勘所
  • debugの方法
  • 環境変数 / 遅延展開

実行方法

  • batファイルは、

    • CMDで、手でコマンドを逐次実行する手順を、ほぼそのまま、batファイルに記述して、
    • 実行で順次実行する

    ためのファイルです。

  • batファイルはCMDの中で実行します。

    • エクスプローラ上でダブルクリックすると、
    • CMDが開いて、その中で実行、
    • 終了すると、CMDが閉じます。

ヘルプ、サンプル

  • ヘルプ
    コマンドそれぞれの構文については記述しません。
    コチラの様に /? をつけて実行するとヘルプが表示されます。
  • サンプル
    サンプルや例が必要であれば、以下の様に検索すると多数見つかります。
site:microsoft.com バッチファイル for

勘所

コマンドライン引数と変数

引数の指定

batファイルを呼び出すときに、引数を指定できます。

testbat.bat arg1 arg2

引数の取出

batファイル内では、引数は %数字 で取り出します。

echo arg1 は %1
echo arg2 は %2

代入、表示、置換

batファイル内で、引数を変数に代入したり(set 変数名=値)、
変数を表示したり(変数の場合は %変数名% で囲む)、
変数の一部の文字を置き換えたり(%変数名:文字列1=文字列2%)できます。

set a1=%1
echo a1 は %a1%
echo 文字置き換え %a1:g=G%

引数の数

%数字 は 1 から 9 まで使用できます。
もし batファイルの引数が 10個以上必要な場合は、shift を使って、引数を1つ前へずらします。

:_nextparam
echo %1
shift
if NOT "%~1" == "" goto :_nextparam
:_end

batファイル名

  • 引数の数字に 0 を指定すると、batファイル名を取り出すことも出来ます。
    • 例えば、batファイルのファイル名から拡張子違いのデータファイル名を生成するには、以下の様にします。
    • batファイル名が c:\temp\test1.bat であれば、"c:\temp\test1.csv" が変数 %dat% に代入されます。
set dat="%~dpn0.csv"
  • %0 は batファイル自身を表し、
  • ~ は 次の文字に従って解釈することを指定、
  • dpn は ドライブ・フォルダパス・ファイル名 を取り出します。
  • 最後に .csv をくっつけます。

変数と環境変数

batファイルでは、%変数名% は、環境変数と共通です。

  • Windowsの環境変数は、
    • コンピュータ >> プロパティ >> 詳細設定 に設定があります。
    • この内容は、batファイルから %環境変数名% で参照できます。
  • batファイル内での環境変数は、
    • 下記でのみ、参照できます。
      • batファイル内
      • および、batファイルから呼び出すコマンド
    • set 環境変数名=値 を記述しても、
      コンピュータ >> プロパティ >> 詳細設定 の環境変数は変更されません。

※ 恒久的に設定するには setx を使う(環境変数の設定方法を参照)。
また、setlocal / endlocal で囲むと、変更をその範囲に閉じ込められる。

「"」の除去

引数、変数は、" " で囲んだまま展開されます。

以下の a1.bat ファイルがある場合、

set a=%1abc

a1 "ABC" と実行すると、以下の様に展開されて set が実行され、変数 a に代入されます。

set a="ABC"abc

「"」を処理するには、%~1 の様に「~」をつけて「"」を取り去ります。

set a=%~1abc     →  set a=ABCabc
set a="%~1abc"   →  set a="ABCabc"

余分な「"」を取り去りつつ、全体を「"」で囲むことができます。

「"」の扱いは、例えば if文 でどう記述するか、どう展開されるか、に影響します。
batファイルが以下の場合、

if %1 == ABC (
   echo ok
)

a1 ABC と起動すると ok ですが、a1 "ABC" と起動すると ok になりません。
この場合、以下の様にすると、a1 "ABC" a1 ABC どちらでも ok になります。

if "%~1" == "ABC" (
   echo ok
)

csvファイルの読み取り

for文を使って、区切り文字(delims=)、カラム(tokens=)を指定して読み取ります。

下の batファイルは、csv の 2つめ・3つめ を echo します。
また batファイルの引数に指定した値を 1カラム目に持つ行の 4カラム目を表示します。
for文の ( ) 内は、' ' で囲んで、コマンドの出力から得ることを指定しています。

batファイル: for_3.bat

@setlocal
@echo off
set csv="%~dpn0.csv"
for /F "tokens=1,2,3,4 delims=," %%a in ('cmd.exe /c type %csv%') do (
  echo %%b %%c
  if "%%a" == "%~1" (
    echo 引数で指定されたパラメタは %%d です
  )
)
@endlocal

実行例: for_3.bat 123

bbb ccc
33 44
234 456
引数で指定されたパラメタは 678 です

for文に指定した %%atokens= に指定した数に従って、
%%a %%b %%c … の順に自動で変数名が使われます。

batファイルの変数は10個を超えると、shiftを使うなど、面倒が生じますが、
事前にパラメタを設計するようなケースでは、パラメタ情報をcsvに用意しておき、
for文で取り出しながら、必要なバッチ処理をまとめて行う、というような処理も作れます。

上の例での注意。

  • csvの値に「,」を含めることは出来ません。「,」は区切り文字です。
  • "aa,bbb" の様にして " で囲むことも出来ません。

上の for文は ( ) 内に type コマンドを書きましたが、
下の様に ( ) 内にファイル名を書くこともできます。ただし、この場合は " " で囲んでいないことに注意。

for /F %%a in (for_3.csv) do (
  echo %%a
)

ファイル名にスペースを含む場合は " " で囲みたいところですが、
下の様に書くとファイル名そのものが変数に設定されます。

for /F %%a in ("c:\temp\data files\for_3.csv") do (
  echo %%a
)

※ この場合は usebackq を付けて for /F "usebackq" %%a in ("c:\temp\data files\for_3.csv")
と書けば、ファイル名として解釈させられる。

内部でコマンド実行

複数行に渡って記述する

改行を入れてコマンドライン引数を複数の行に分けるには、
Linuxの「\」ではなく「^」が使える。

改行入りのパラメタを入力したい

LinuxのBashのEOF(ヒアドキュメント)は、WindowsのBATだと「()」で記述できる、
と言う記述があるがコマンドライン引数には適用できないので、
当該引数がファイル入力をサポートしていないかを確認する。

別のBATファイルを呼び出す

CALLを使用する。

CALL BATファイル名 引数1 引数2 ...

※ CALL を付けずに別の bat を書くと、呼び出し元には戻らない(プロセスが乗っ取られる)。

変数の遅延展開

遅延展開 無効

for文で do ( ... )( ) 内に複数行に渡って記述できますが、
( ) 内で設定した変数を使用する場合は、変数が展開されるタイミングについて注意が必要です。

@setlocal
@echo off
set csv="%~dpn0.csv"
for /F "tokens=1,2,3,4 delims=," %%a in ('cmd.exe /c type %csv%') do (
  set /A var1=%%b + %%c
  echo %%b + %%c は %var1%
)
@endlocal

実行例:

bbb + ccc は
33 + 44 は
234 + 456 は

このbatファイルで、echo の %var1% は、for文を開始する直前に置き換えられて、空文字になっています。

遅延展開 有効

以下のbatファイルの様に

  • setlocal ENABLEDELAYEDEXPANSION を指定して遅延展開を有効にし、
  • 変数を !変数名! と記述します。
@setlocal ENABLEDELAYEDEXPANSION
@echo off
set csv="%~dpn0.csv"
for /F "tokens=1,2,3,4 delims=," %%a in ('cmd.exe /c type %csv%') do (
  set /A var1=%%b + %%c
  echo %%b + %%c は !var1!
)
@endlocal

実行例:

bbb + ccc は 0
33 + 44 は 77
234 + 456 は 690

遅延展開を有効にすると、!変数名! が現れた時点で値に置き換えられます。

終了コード

batファイルの終了コードは、exit コマンドと共に指定します。

exit /B コード

ただし、

  • exitコマンドはbatファイルが終了するので、
  • batファイルの終了箇所で exit を使用します。
@setlocal
@echo off
set exitcode=0

dir c:\tempo
if %ERRORLEVEL% NEQ 0 (
  set exitcode=2
  echo dirがエラーです
)

exit /B %exitcode%
@endlocal
goto :EOF

このbatファイルは、

  • exit の後にある @endlocalgoto :EOF は実行されません。
  • exit /B が endlocal と goto :EOF を含んだ動作をします。

補足: exit/B なしで使うと CMD プロセスごと終了する。 呼び出し元の bat に戻りたい場合は必ず /B を付ける。

debug方法

batファイルの効果的なdebugツールはありません。

  • batファイル冒頭の @echo off をコメントアウトする
  • echo を随所に埋め込んで、値を表示する
  • pause を埋め込んで、その時点で一時停止させてみる

くらいしか方法がありません。debugが終わったら、元に戻すのを忘れないでください。

以下の様に、debug用の echo を用意すると、戻す作業が少し簡単になるかもしれません。

@setlocal
@echo off

call :_debugprint 引数を確認: %1 %2 %3
for /F "delims=" %%a in ('dir "%~1"') do (
  echo %%a
)

@endlocal
goto :EOF

:_debugprint
@rem  debugが終わったら、echo をコメントアウトする
echo %*
goto :EOF

移行メモ(正誤): 原文の for 文は for /F "delims=" %%a in ('dir "%~1"') (do が抜けていたため構文エラーになる。do を補った。

サンプル

約数を求める

batファイル: yakusu.bat

@setlocal
@echo off

if "%1" == "" (
  goto :_end
)

set a=%1
set /A b=%a% - 1

:_next
if NOT %b% GEQ 1 goto :_end
set /A c=%a% / %b% * %b%
if %c% == %a% (
  echo %b%
)
set /A b=%b% -1
goto :_next

:_end
@endlocal
goto :EOF

実行例: yakusu.bat 32

16
8
4
2
1

以下の set /A は、割って掛けることで、割り切れる数値かを確認をしています
set /A の除算は整数除算なので、割り切れない場合は元の値に戻らない)。

set /A c=%a% / %b% * %b%

カレントディレクトリ以下の VC++中間ファイルを削除

batファイル: del-vc-obj.bat

@setlocal
@echo off
call :_vcfiles
@endlocal
goto :EOF

:_vcfiles
for %%i in (*.obj *.pcb *.pch *.ncb *.pdb *.ilk *.idb) do echo "%cd%\%%i" && del "%cd%\%%i"
for /D %%i in (*) do (
  pushd "%%i"
  call :_vcfiles
  popd
)
goto :EOF

実行例

このbatファイルを実行すると、カレントディレクトリ以下のVC++の中間ファイルを全て削除します。

%cd%CMDのカレントディレクトリを表す組み込みの変数です。
2つめのfor文でサブディレクトリを列挙して、pushd でカレントディレクトリを記憶しつつ、
サブディレクトリへ移動し、call :_vcfiles で自身を再帰呼び出ししています。

参考


Tags: シェル, インフラストラクチャ, Windows

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally