S-JIS[2006-07-07/2013-03-05] 変更履歴

MS-DOSバッチファイル

DOSのコマンドをファイルに書いておき、バッチとして実行することが出来る。(UNIXのシェルスクリプトに相当)


実行方法


bat

PATH
 


C:\temp>test.bat
C:\temp>test
C:\>C:\temp\test.bat
C:\>"C:\temp\test.bat" …ダブルクォーテーションでくくっても可


[2013-03-05]
C:\temp> test.bat aaa bbb ccc


=;,

> type test.bat
@echo args: %1 %2 %3 %4

> test.bat a=b,c;d
args: a b c d

> test.bat "a=a" "b,b" "c;c" d
args: "a=a" "b,b" "c;c"d

 Microsoft (=) 






echo off

CALL

for


@echo off




@echo off

 UNIXsh  -x
echo off
echo offecho off@
echo off@
echo off()  echo on


[2007-03-07]


.bat

echo "start"
test.bat
echo "ここへは戻って来ない!"

CALL使exit /b使

.bat

echo "start"
call test.bat
echo "戻ってきた" %ERRORLEVEL%
pause

exit /bexitexit
cmd /c使exit 

exit.bat

echo "start"
cmd /c test.bat
echo "返ってきた♪" %ERRORLEVEL%
pause


WindowsXP[2009-11-14]
C:\WINDOWS\system32\cmd.exe

title使
title ウィンドウのタイトル


[2009-11-14]

CD

%0
set BATDIR=%~dp0

%0~d~p~dp+

C:\temp\test.batBATDIRC:\temp\
\%BATDIR%\zzz.txt
C:\temp\\zzz.txt\2
%BATDIR%zzz.txt

UNIX

使


使使

使set


for使


UNIX
変数 内容 UNIX相当
%ERRORLEVEL% 直前に実行されたコマンド(や関数)の戻り値 $?
%0 実行コマンド名 $0
%1 %2 … %9 実行時引数(個別) $1 $2 …
%* 全引数 $* $@

shift1UNIXshift
%0%1%1%2%9%10

%0%*UNIX
%0shift /1%1


for
help callcall /?help forfor /?

1dpnx[2009-11-14]

c:\temp%1"abc"abc%2zzz.txt
指定方法 説明
%~変数 %変数の値がダブルクォーテーションでくくられているとき、ダブルクォーテーションを削除したものになる。 echo %~1
→「abc」が表示される
%~f変数 %変数の値をフルパス(絶対パス)に変換したものになる。
..」等の相対パス指定が入っていた場合、それらが取り除かれた正しい状態になる。
echo %~f1
→「C:\temp\abc」が表示される
%~d変数 %変数の値をフルパスで扱う際のドライブ名になる。 echo %~d1
→「C:」が表示される
%~p変数 %変数の値をフルパスで扱う際のパス名になる。 echo %~p1
→「\temp\」が表示される
%~dp変数 %変数の値をフルパスで扱う際のドライブ+パス名になる。[2009-11-14] echo %~dp1
→「C:\temp\」が表示される
%~n変数 %変数の値のファイル名部分(拡張子なし)になる。 echo %~n2
→「zzz」が表示される
%~x変数 %変数の値の拡張子(ピリオド付き)になる。 echo %~x2
→「.txt」が表示される
%~nx変数 %変数の値のファイル名(拡張子あり)になる。 echo %~nx2
→「zzz.txt」が表示される
%~s変数
%~fs変数
%変数の値を短縮形(dir /xと同等)に変換したものになる。[2008-08-02]
はずなのだが、なんだかバグがある(正しい形にならない事がある)。(WindowsXP SP3)
 
%~a変数 %変数の値のファイルが存在するとき、そのファイルの属性になる。 echo %~a2
→「--a------」が表示される
%~t変数 %変数の値のファイルが存在するとき、そのファイルの更新日時になる。 echo %~t2
→「2006/07/07 23:59」が表示される
%~z変数 %変数の値のファイルが存在するとき、そのファイルのサイズになる。 echo %~z2
→「5」が表示される
%~$環境変数:変数 %変数の値のファイルが 環境変数(例えばPATHやCLASSPATH)で列挙されているディレクトリに存在するかどうか調べ、存在していればそのファイル(フルパス)になる。
「~」と「$」の間には前述のfd等の指定を入れることが出来、それぞれの指定に従って変換される。
この機能を使うと、UNIXのwhichもどきが作れる。
%3が「help.exe」のとき、
echo %~dpnx$PATH:3
→「C:\WINDOWS\system32\help.exe」が表示される

環境変数の加工方法


バッチの構文

if

if 条件 コマンド if 条件 (コマンド) else コマンド

if 条件 (コマンド) else (コマンド)
if 条件 (
コマンド

) else (
コマンド

)

UNIXif

( )

else 
ifelseif()else
else

使
比較演算子
== EQU NEQ 比較
LSS LEQ
GTR GEQ
大小比較
単項演算子
NOT 否定 if not "%1" == "" echo 引数があります
DEFINED 環境変数が存在するとき、真 if defined TMP echo 有る
EXIST ファイル(やディレクトリ)が存在するとき、真
ファイル名をダブルクォーテーションでくくることも出来るが、末尾のスペースは無視される模様。
if exist zzz.txt echo 在る
ERRORLEVEL %ERRORLEVEL%が値以上
なぜこんな演算子がわざわざあるかについては、注意点を参照。
if errorlevel 1 echo エラー


ANDOR



"1"1

/i
if/i %1 equ abc (echo 一致!) else (echo 不一致)


thenelse使

for

for /L %変数 in (開始,増分,終了) do コマンド for /L %変数 in (開始,増分,終了) do (
コマンド

)

do
>for /L %i in (1,1,10) do echo %i

110(10,1,10)10(11,1,10)


for1
for使%i%%i%2

%i
do使

for each

for %変数 in (複数の値) do コマンド

UNIXfor
in1使

@使2[2009-11-14]
@for 〜do@コマンド

>for %i in (aa bb cc) do echo %i
>for %i in (aa,bb,cc) do echo %i
>for %i in (aa;bb;cc) do echo %i

aabbcc

))
>for %i in (aa bb) cc) do @echo %i
cc) の使い方が誤っています。
>for %i in (aa bb^)cc) do @echo %i
aa
bb)
cc

>for %i in (%CLASSPATH%) do @echo %i

CLASSPATH1
for %%i in (%*) do @echo %%i バッチ内で使う例

1

>for %i in (C:\*) do @echo %i

>for %i in (C:\lib1\*.jar C:\lib2\*.jar) do @echo %i


;[2009-02-20]
>for /d %i in (C:\*) do @echo %i

/d
>for /r %i in (*.txt) do @echo %i

/r

>for /f "オプション" %i in (ファイル名) do @echo %i …ファイルの内容(各行)でループ
>for /f "オプション" %i in ("文字列")   do @echo %i …文字列を処理
>for /f "オプション" %i in ('コマンド') do @echo %i …コマンドの実行結果(標準出力の各行)でループ


%i1


skip=行数 ファイルのその行数分だけスキップする。
eol=字 その文字で始まる行は、コメント行として無視する。
>for /f "eol=;" %i in (";コメント") do @echo %i
tokens=番号 その番号個目のカラムを変数に入れる。(デフォルトでは1)
>for /f "tokens=2" %i in ("a b c") do @echo %i
b

番号をカンマ区切りで列挙すると、そのカラムが変数に入れられる。
変数は最初に指定されていたものから順番に、暗黙に増える。(指定したのがiならj,k,l,…、aならb,c,d,…)

>for /f "tokens=1,3" %i in ("a b c") do @echo %i %j
a c

ハイフンでカラムの範囲を指定することも出来る。

>for /f "tokens=2-4" %i in ("a b c d e") do @echo %i %j %k
b c d

番号の代わりに「*」を指定すると、行の残りの部分全てになる。

>for /f "tokens=1,*" %i in ("a b c d e") do @echo %i -- %j
a -- b c d e
>for /f "tokens=*" %i in (test.txt) do @echo %i	…行を全部表示
delims=文字 デリミター(区切り文字)を指定する。(デフォルトではスペース)
>for /f "delims=,; tokens=1-3" %i in ("abc;def,ghi") do @echo %i %j %k
abc def ghi
usebackq ファイル名指定の引用符の意味を変える。
デフォルトでは 引用符を何も付けないとファイル名指定だが、空白が入っているファイル名には対応していない。
このオプションを付けることにより、ダブルクォーテーションがファイル名指定になる。(したがって空白が入っているファイル名を指定できるようになる)
>for /f "usebackq" %i in ("ファイル名") do @echo %i	…ファイルの内容でループ
>for /f "usebackq" %i in ('文字列')     do @echo %i	…文字列を処理
>for /f "usebackq" %i in (`コマンド`)   do @echo %i	…コマンドの実行結果でループ

ファイルの内容を環境変数に入れる例


for/ffor[2012-07-14]

%%
@echo off
for /f %%i in (test.txt) do set ZZZ=%%i
echo ZZZ=%ZZZ%



4
@echo off
type test2.txt

for /f "tokens=4" %%i in (test2.txt) do set ZZZ=%%i
echo ZZZ=%ZZZ%
this is a pen
ZZZ=pen

for
@echo off
type test3.txt

for /f "skip=2 tokens=4" %%i in (test3.txt) do (
  set ZZZ=%%i
  goto END_LOOP1
)
:END_LOOP1

echo ZZZ=%ZZZ%
this is a pen
this is a apple
this is a orange
this is a foo
ZZZ=orange


for/f[2012-07-14]
ERRORLEVEL

%%
@echo off

for /f %%i in ('date /t') do set ZZZ=%%i

echo date=%ZZZ%
date=2012/07/14

for
@echo off

for /f "delims=/ tokens=1-3" %%i in ('date /t') do (
  set ZZZ1=%%i%%j%%k
  set ZZZ2=%%i-%%j-%%k
)

echo date=%ZZZ1%
echo date=%ZZZ2%
date=20120714
date=2012-07-14

DATE使

goto

:ラベル
goto ラベル

MS-DOSgoto
if%~1 == abc goto match
echo 不一致
goto :EOF

:match
echo 一致

:EOFgoto
goto::EOFgoto

exit /b使

switch

:ラベル
goto %環境変数%

MS-DOSにはUNIXのcaseに当たるものは無いが、gotoのラベルは変数を使って動的に変えることができるので、これで代用することが出来なくはない。

set CASE=1
goto caseA_%CASE%		…CASEの値に応じて、:caseA_1:caseA_2へ飛ぶ
:caseA_1
  echo case1
  goto :caseA_end
:caseA_2
  echo case2
  goto :caseA_end
:caseA_end

このやり方だと、「その他」に当たるものが出来ないが…。
(存在しないラベルへ飛ぼうとするとエラーになるから)


サブルーチン

定義 呼び出し
:ラベル
setlocal

endlocal
exit /b 〔戻り値〕
call :ラベル
call :ラベル 引数

UNIX
MS-DOS
call
call
goto




setlocal使
endlocalendlocalsetlocalendlocal
使setlocal使

exit /bcall exit /b

exit /b %ERRORLEVEL%
%ERRORLEVEL%

test.bat
@echo off
echo 呼び出し前:%*
call :sub aa %* bb
echo 戻り値:%ERRORLEVEL%
echo 呼び出し後:%*
exit /b

:sub
echo 呼び出された:%*
exit /b99
>test.bat foo zzz
呼び出し前:foo zzz
呼び出された:aa foo zzz bb
戻り値:99呼び出し後:foo zzz


exit /b
call
exit

exit /b %ERRORLEVEL%
0%ERRORLEVEL%



exit /b 0



>test.bat || echo fail

test.bat
test.batexit /b 10

>test.bat &iferrorlevel 1 echo fail …test.batの戻り値が1以上のとき「echo fail」を実行



>test.bat & if %ERRORLEVEL% neq 0 echo fail
>test.bat & echo %ERRORLEVEL%


%ERRORLEVEL%0
>test.bat & if 0 neq 0 echo fail
>test.bat & echo 0

test.bat%ERRORLEVEL%&
ERRORLEVELif


使ifforhelp  forfor /?
>set var=aaa
>set var=bbb & echo %var%  →「set var=bbb & echo aaa」と展開されてから実行される
aaa
>echo %var%
bbb    →「set var=bbb」が実行されなかったわけではないので、後から見ればちゃんとセットされている
set var=1
if %var% == 1 (   →「if 1 == 1 (
 set/a var=%var% + 2     set/a var=1 + 2
 echo %var%      echo 1
)      )」と展開されてから実行される
set list=
for %%i in (aa bb) do @set list=%list%;%%i →「for %i in (aa bb) do @set list=;%i」と展開されてから処理されるので、
echo %list%     「@set list=;aa」「@set list=;bb」が実行される


使
>set var=123
>set var=234 & echo 通常:%var% 遅延:!var!
通常:123 遅延:!var!

>cmd /v:on     …遅延環境変数を有効にして新しいコマンドプロンプトを起動

>set var=123
>set var=234 & echo 通常:%var% 遅延:!var!
通常:123 遅延:234

>exit      …元のコマンドプロンプトへ戻る


使[2007-06-15]
set var=1
if %var% == 1 (call :add %var%)
exit/b

:add
set/a var=%var% + 2
echo %var%
set list=
for %%i in (aa bb) do @call :add %%i
echo %list%
exit/b

:add
@set list=%list%;%1


使[2007-10-26]
echo使 

test_more.bat
@echo off
more


> type aaa.txt | test_more
a1
a2

> test_more < aaa.txt
a1
a2


for使
findstr使UNIXcat使MS-DOStype使

test_echo.bat
@echo off
for /f %%i in ('findstr .*') do echo %%i


> type aaa.txt | test_echo
a1
a2

> test_echo < aaa.txt …なぜか何も出力されない

使



test_echo2.bat
@echo off
findstr .* | for /f %%i in ('findstr .*') do @echo %%i


> type aaa.txt | test_echo2
a1
a2

> test_echo2 < aaa.txt
a1
a2

 docall使   


()

 /