MS-DOS コマンドプロンプトとバッチファイルに関するTips。 ここで紹介するものは主にWindows XP, Windows 7にて検証したもの(他のOSでは未検証)。
環境変数
- 値を代入するときは、「set 変数名=値」
- 値を参照するときは、「%変数名%」
- 値の一部分を取得するときは、「%変数:~開始位置,長さ%」
echo
echoの使い方。
echo on/off
echo on(デフォルト)の場合は、バッチファイルのコマンドがそのまま表示される。 echo offの場合は、コマンドは表示されず、結果のみが表示される。
echo 処理を始めます
echo echoを用いてメッセージを表示する
C:\Documents and Settings\smdn\デスクトップ>echo 処理を始めます 処理を始めます C:\Documents and Settings\smdn\デスクトップ>echo echoを用いてメッセージを 表示する
echo offにすると、バッチファイルで実行するコマンドの部分が表示されなくなる。
echo off
echo 処理を始めます
echo echoを用いてメッセージを表示する
C:\Documents and Settings\smdn\デスクトップ>echo off
処理を始めます
echoを用いてメッセージを表示する
さらに、「@echo off」とすると、「echo off」を実行するときのコマンドも表示されなくなる。
@echo off
echo 処理を始めます
echo echoを用いてメッセージを表示する
処理を始めます echoを用いてメッセージを表示する
メッセージを表示する
echoに続く文字列はそのまま表示される。 環境変数は値が展開されて表示される。 「echo.」とすると空行が表示される。
echo 処理を始めます
echo 今日の日付は%DATE%です
echo.
echo OSは%OS%です
処理を始めます 今日の日付は2007/05/19です OSはWindows_NTです
set
setの使い方。
すべての環境変数を表示する
setコマンドをオプション無しで実行すると、現在定義されているすべての環境変数が表示される。
C:\>set
ALLUSERSPROFILE=C:\Documents and Settings\All Users
APPDATA=C:\Documents and Settings\smdn\Application Data
CLIENTNAME=Console
CommonProgramFiles=C:\Program Files\Common Files
COMPUTERNAME=HIKARI
ComSpec=C:\WINDOWS\system32\cmd.exe
FP_NO_HOST_CHECK=NO
HOMEDRIVE=C:
HOMEPATH=\Documents and Settings\smdn
LOGONSERVER=\\HIKARI
NUMBER_OF_PROCESSORS=1
OS=Windows_NT
Path=C:\PROGRA~1\JUSTSY~1\JSLIB32;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\Syst
em32\Wbem
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH
PROCESSOR_ARCHITECTURE=x86
PROCESSOR_IDENTIFIER=x86 Family 6 Model 15 Stepping 8, GenuineIntel
PROCESSOR_LEVEL=6
PROCESSOR_REVISION=0f08
ProgramFiles=C:\Program Files
PROMPT=$P$G
SESSIONNAME=Console
SystemDrive=C:
SystemRoot=C:\WINDOWS
TEMP=C:\DOCUME~1\SANTAM~1\LOCALS~1\Temp
TMP=C:\DOCUME~1\SANTAM~1\LOCALS~1\Temp
USERDOMAIN=HIKARI
USERNAME=smdn
USERPROFILE=C:\Documents and Settings\smdn
VS80COMNTOOLS=C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\
windir=C:\WINDOWS
環境変数を設定する
set LOGFILE=sample.log
set LOGDIR=.\logs\
echo %LOGDIR%%LOGFILE%
.\logs\sample.log
キーボードからの入力を環境変数に代入する
/pオプションを指定してsetコマンドを実行すると、キーボードからの入力を環境変数に代入することが出来る。
echo ログファイル名は?
set /p LOGFILE=
set LOGDIR=.\logs\
echo %LOGDIR%%LOGFILE%
ログファイル名は? test.log .\logs\test.log
また、次の例のようにプロンプト文字列を指定することも出来る。
set /p LOGFILE=ログファイル名は?
set LOGDIR=.\logs\
echo %LOGDIR%%LOGFILE%
ログファイル名は? test.log .\logs\test.log
四則演算等の演算を行う
/aオプションを指定してsetコマンドを実行すると、四則演算等の演算を行うことが出来る。
set A=12
set B=8
set /a RESULT=%A% + %B%
echo %A% + %B% = %RESULT%
set /a RESULT=%A% - %B%
echo %A% - %B% = %RESULT%
set /a RESULT=%A% * %B%
echo %A% * %B% = %RESULT%
set /a RESULT=%A% / %B%
echo %A% / %B% = %RESULT%
set /a RESULT=%A% %% %B%
echo %A% %% %B% = %RESULT%
12 + 8 = 20 12 - 8 = 4 12 * 8 = 96 12 / 8 = 1 12 % 8 = 4
+=演算子や-=演算子などの複合代入演算も行うことが出来る。 なお、インクリメント・デクリメント演算子は無いので、代わりに += もしくは -= を使う必要がある。
set X=3
echo %X%
set /a X+=1
echo %X%
set /a X-=1
echo %X%
set /a X*=2
echo %X%
set /a X/=3
echo %X%
3 4 3 6 2
文字列操作
連結
2つの変数を並べることで、文字列の連結を行うことが出来る(連結するための結合演算子は無い)。
set STR1=foo
set STR2=bar
set STR3=%STR1%%STR2%
echo %STR3%
set STR4=%STR3%baz
echo %STR4%
foobar foobarbaz
部分文字列の取得
「%変数:~開始位置,長さ%」とすることで変数の内容から部分文字列を取得できる。 長さを省略したり、負の値を指定することも出来る。 開始位置に負の値を指定すると末尾n文字目からの部分文字列、長さに負の値を指定すると末尾n文字目までの部分文字列を取得出来る。 なお文字の番号は0から始まるため、先頭の文字は0番目となる。
書式と得られる結果をまとめると次のようになる。
書式 | 得られる部分文字列 (下線部分) |
---|---|
%STR:~0% | 0123456789 |
%STR:~0,3% | 0123456789 |
%STR:~3% | 0123456789 |
%STR:~3,5% | 0123456789 |
%STR:~3,-5% | 0123456789 |
%STR:~-5% | 0123456789 |
%STR:~-5,2% | 0123456789 |
%STR:~-5,-2% | 0123456789 |
set STR=0123456789
echo %STR:~0%
echo %STR:~0,3%
echo %STR:~3%
echo %STR:~3,5%
echo %STR:~3,-5%
echo %STR:~-5%
echo %STR:~-5,2%
echo %STR:~-5,-2%
0123456789 012 3456789 34567 34 56789 56 567
置換
「%変数:置換前の文字列=置換後の文字列%」とすることで変数の一部分を置換した結果を得ることが出来る。 最初に一致した箇所でなく、一致する箇所全てが置換される。 置換後の文字列を省略すると空の文字列に置換されることとなり、部分文字列を削除することが出来る。
set A=hogehogehoge
echo %A% : %A:o=a%
set B=test.log
echo %B% : %B:.log=.log.1%
set C=test.log.bak
echo %C% : %C:.bak=%
hogehogehoge : hagehagehage test.log : test.log.1 test.log.bak : test.log
キー入力があるまで処理を中断する
pauseを用いると、その部分で処理を中断し、キー入力があるまで待機する。
echo 処理を始めます
pause
echo 完了しました
処理を始めます 続行するには何かキーを押してください . . . 完了しました
年月日を変数に代入する
システム変数%DATE%で取得できる日付の文字列を切り出して、年月日をそれぞれ別々の変数に代入する。
set YEAR=%DATE:~0,4%
set MONTH=%DATE:~5,2%
set DAY=%DATE:~8,2%
echo Date: %DATE%
echo Year: %YEAR%
echo Month: %MONTH%
echo Day: %DAY%
Date: 2007/05/19 Year: 2007 Month: 05 Day: 19
「%変数:~開始位置,長さ%」で変数の一部分を切り出すことが出来る。 システム変数%DATE%の書式は「yyyy/mm/dd」になっているので、それぞれ一部分を切り出して別々の変数に代入することで年月日を取得できる。
時刻についても同様に取得できる。
set HOUR=%TIME:~0,2%
set MINUTE=%TIME:~3,2%
set SECOND=%TIME:~6,2%
echo Time: %TIME%
echo Hour: %HOUR%
echo Minute: %MINUTE%
echo Second: %SECOND%
Time: 16:02:09.71 Hour: 16 Minute: 02 Second: 09
コメント
REMを使えばバッチファイル中にコメントを記述できるが、行頭にREMが並ぶのは見づらい。
REM 年月日を取得する
set YEAR=%DATE:~0,4%
set MONTH=%DATE:~5,2%
set DAY=%DATE:~8,2%
REM 年月日を表示する
echo Year: %YEAR%
echo Month: %MONTH%
echo Day: %DAY%
REMの代わりに、GOTOで使用するラベルを定義するために用いるコロン(:)を応用することで、コロン(:)で始まる行をコメント行にすることができる。
:: 年月日を取得する
set YEAR=%DATE:~0,4%
set MONTH=%DATE:~5,2%
set DAY=%DATE:~8,2%
:: 年月日を表示する
echo Year: %YEAR%
echo Month: %MONTH%
echo Day: %DAY%
コロン(:)の後ろに続く文字列がラベルとして使用されない限りは意味のない行となるため、コロン(:)で始まっていればその後ろに続く文字は何でもOK。 下記のいずれの表記も文法上エラーとはならず、また意味のない行となるため、コメント行となる。
:: コメント行
:# コメント行
:! コメント行
:% コメント行
:// コメント行
乱数を取得する
システム変数%RANDOM%
を参照すると0から32767までの乱数を取得できる。
set RANDVAL=%RANDOM%
終了コードを取得する
システム変数%ERRORLEVEL%
を参照すると直前に実行したコマンドの終了コードを取得できる。
:: 実行して成功となるコマンド
success.exe
echo %ERRORLEVEL%
:: 実行して失敗となるコマンド
failure.exe
echo %ERRORLEVEL%
0 1
ファイルの有無で処理を分岐する
if exist文を用いるとファイルが存在する場合の処理を記述できる。 さらにgoto文と組み合わせることで、ファイルが存在する場合とそうでない場合で処理を分岐させることが出来る。
set FILE=test.txt
if exist %FILE% ( goto FOUND ) else goto NOTFOUND
:FOUND
echo ファイル%FILE%が見つかりました
goto END
:NOTFOUND
echo ファイル%FILE%は存在しません
goto END
:END
echo 終了
if not exist文を用いると、ファイルが存在しない場合の処理を記述できる。
set FILE=test.txt
if not exist %FILE% echo ファイル%FILE%は存在しません
引数
%番号
とするとバッチファイルに渡されたコマンドライン引数を取得することができる。 例えば%1
には1番目、%2
には2番目に指定された引数が格納される。 引数に与えられたダブルクオーテーション"
などはそのまま取得される。 %0
にはバッチファイル自体のパス(実行時のパス)が格納される。
@echo off
echo 0: %0
echo 1: %1
echo 2: %2
echo 3: %3
E:\>test.bat param1 "param 2" test.txt 0: test.bat 1: param1 2: "param 2" 3: test.txt E:\>cd sample E:\sample>..\test.bat param1 "param 2" test.txt 0: ..\test.bat 1: param1 2: "param 2" 3: test.txt
引数の展開と修飾子
%~(番号)
のように引数番号の前に~
を記述すると、引数を展開する際にダブルクオーテーション"
が削除される。
@echo off
echo %1
echo %~1
echo %2
echo %~2
E:\>test.bat param1 "param 2"
param1
param1
"param 2"
param 2
さらに、%~f1
のように%~(修飾子)(番号)
と記述すると、修飾子によって展開される結果が次のように変わる。 修飾子を指定した場合も同様にダブルクオーテーション"
が削除される。
修飾子 | 展開時の動作 |
---|---|
f
|
引数をフルパス名に展開する |
p
|
引数からファイル名を除いたディレクトリ部分に展開する |
n
|
引数から拡張子を除いたファイル名に展開する |
x
|
引数を拡張子だけに展開する |
d
|
引数をドライブレターと: だけ(C: など)に展開する |
t
|
引数をファイルの日時に展開する |
z
|
引数をファイルのサイズに展開する |
@echo off
echo %1
echo %~1
echo f: %~f1
echo p: %~p1
echo n: %~n1
echo x: %~x1
echo d: %~d1
echo t: %~t1
echo z: %~z1
E:\>test.bat ".\sample\foo.txt"
".\sample\foo.txt"
.\sample\foo.txt
f: E:\sample\foo.txt
p: \sample\
n: foo
x: .txt
d: E:
t: 2013/12/16 00:06
z: 45
なお、これらの修飾子は組み合わせて複数指定することもできる。 そのため、次のように展開時にファイル名や拡張子を別のものに置き換えることもできる。
@echo off
::一つ目の引数を拡張子を含むファイル名に展開
echo %~nx1
::一つ目の引数をドライブ名を含むディレクトリに展開
echo %~dp1
::一つ目の引数の拡張子を".bak"に置き換えて展開
echo %~dpn1.bak
::一つ目の引数のファイル名に"backup-"を前置して展開
echo %~dp1backup-%~nx1
E:\>test.bat ".\sample\foo.txt"
foo.txt
E:\sample\
E:\sample\foo.bak
E:\sample\backup-foo.txt
他のバッチファイルを呼び出す
callコマンドを用いると、他のバッチファイルを呼び出すことができる。 このとき、引数を指定することもできる。
@echo off
set VAL1=value 1
set VAL2=value 2
call b.bat 引数1 "引数 2" %VAL1% "%VAL2%"
echo 1: %1
echo 2: %2
echo 3: %3
echo 4: %4
echo 5: %5
echo 6: %6
echo VAL1=%VAL1%
echo VAL2=%VAL2%
E:\>a.bat
1: 引数1
2: "引数 2"
3: value
4: 1
5: "value 2"
6:
VAL1=value 1
VAL2=value 2
環境変数は展開されてから引数として渡されるので、値に空白が含まれていると引数の区切りとみなされ、別々に渡される点に注意が必要。 環境変数に空白が含まれる場合はダブルクオーテーション"
でくくることによりひとつの引数として渡すことができる。 また、callコマンドによって呼び出されたバッチファイルも同一プロセスで実行されるため、呼び先のバッチファイルから呼び元の環境変数を参照することができる。
パイプとリダイレクト
パイプ
コマンド1の標準出力をコマンド2の標準入力に接続するには次のようにする。
コマンド1 | コマンド2
次の例では、typeコマンドによってファイルの内容を標準出力に書き出し、sortコマンドの標準入力に渡すことでsource.txtの内容をソートした状態で表示している。
E:\>type source.txt ab abcd abc a E:\>type source.txt | sort a ab abc abcd
次のように複数のコマンドを連結することができる。
コマンド1 | コマンド2 | コマンド3 | ...
リダイレクト
標準入力
ファイルfileの内容をコマンドcommandの標準入力に渡すには次のようにする。
command < file
標準出力
コマンドcommandが標準出力に出力する内容をファイルfileに書き込むには次のようにする。
command > file
command 1> file
STDOUTのハンドルを表す1は省略することができるので、1>
は単に>
と記述することができる。
標準エラー
コマンドcommandが標準エラーに出力する内容をファイルfileに書き込むには次のようにする。
command 2> file
標準出力の場合とは異なり、STDERRのハンドルを表す2は省略することができないので、2>
を単に>
と記述することはできない。
標準出力・標準エラーの追記書き込み
標準出力・標準エラーをリダイレクトする場合、>>
や2>>
と記述することでリダイレクトの際に書き込まれる内容を上書きではなくファイルに追記させることができる。
command >> file
command 2>> file
標準入力と標準出力のリダイレクト
ファイルinput.txtの内容をコマンドの標準入力に渡し、コマンドの標準出力をファイルoutput.txtにリダイレクトする場合は次のようにする。
command < input.txt > outout.txt
標準出力と標準エラーのリダイレクト
標準出力と標準エラーを別々のファイルにリダイレクトする場合は次のようにする。
command > out.log 2> err.log
標準出力と標準エラーを同一のファイルにリダイレクトする場合は次のようにする。
command > out.log 2>&1
これは次のようにすることもできる。
(command 2>&1) > out.log
NULデバイス
UNIXの/dev/null
に相当するものとしてnul
が用意されている。 例えば標準出力をnul
にリダイレクトすれば出力内容はすべて破棄され、一切表示されなくなる。
command > nul
文字コードの変更
chcpコマンドを用いると、使用する文字コードを変更できる。 引数で指定できる主な文字コードは次のとおり。
コード | 名称 |
---|---|
932 | Shift-JIS (デフォルト) |
20932 | EUC-JP (IS X 0208-1990 and JIS X 0212-1990) |
51932 | EUC-JP |
65000 | UTF-7 |
65001 | UTF-8 |
引数を指定せずにchcpコマンドを実行すると、現在の文字コードが表示される。


なお、chcpコマンドで文字コードを変更すると、ウィンドウのサイズとフォントが代わり漢字等が正しく表示されなくなるので、次の手順であらかじめフォントを変更しておく必要がある。
- コマンドプロンプトのプロパティを開く
- 「フォント」タブで「MSゴシック」等のフォントに変更する