DOSコマンドによるバッチファイルの使い方まとめ。普段は使わないけれど、いざという時に使えるとちょっと便利でもある。ただ、改めて文法を調べてみると、むしろ前衛的と言えるぐらいカオスでもあった…。
追記
結論として、DOSコマンドでのファイルの読み書きはオススメしません。文字コードが原則Shift_JISのみなのと、ファイル中に制御記号が含まれていると想定外の処理をすることがあるためです。WSH(VBScript、JScript)やPowerShellのほうが適しています。
基本1:set(変数に値をセット)
・変数へ代入 set NAME=太郎
・変数を参照 echo.%NAME%
・数式を代入 set /A NUM=1+2+3+4
/A
オプションにより、右辺が数式として評価されます。またecho
は画面出力ですが、上の例で%NAME%
が空文字だとエラーメッセージが出てしまいます。それを防ぐためにecho.
と、ドットを付けるようにしましょう。
@echo off
set STR=Hello
set STR=%STR% World
set NUM=3
set /A NUM=%NUM%+5
set /A NUM+=2
echo.%STR%
echo.%NUM%
pause
Hello World
10
もひとつ重要なことに、上記の変数はfor文の中などでは定数のように振る舞います。つまり、for文の実行前に%変数%
が静的に展開されます。実行中に値を変化させたい場合は、setlocal enabledelayedexpansion
を宣言します。遅延環境変数と呼ばれてるようです。そして、変数を参照する時には!変数!
のように、感嘆符で囲みます。
@echo off
setlocal enabledelayedexpansion
set SUM=0
for /L %%i in (0, 1, 10) do (
set CNT=%%i
set /A SUM=!SUM!+!CNT!
)
echo.!SUM!
pause
55
追記
ただし問題点として、遅延環境変数が有効の場合、文字変数中の感嘆符が制御記号扱いとなり感嘆符が消失してしまうので要注意です。
基本2:エスケープ
リダイレクト記号<>
などの制御文字を通常の文字として扱うには、その直前にエスケープ記号^
を置きます。ただし、set
やecho
処理ではその都度、エスケープ記号が消費される(?)ため、余分に記述しておく必要があるようです…。が、遅延環境変数ではその必要はないようです…。カオスな仕様やね…。
@echo off
setlocal enabledelayedexpansion
::通常の環境変数の場合
set AAA=^^^<AAA^^^>
echo.%AAA%
set BBB=^^^<BBB^^^>
echo.%BBB%>>out.txt
::遅延環境変数の場合
set CCC=^<CCC^>
echo.!CCC!
set DDD=^<DDD^>
echo.!DDD!>>out.txt
pause
実例1:テキストファイルを読み込んで、3行目だけ行頭に「AHO」を追記
@echo off
setlocal enabledelayedexpansion
set FILENAME=test.txt
set CNT=0
for /f "delims=" %%S in (%FILENAME%) do (
echo.CNT=!CNT!
if !CNT!==0 (
call>%FILENAME%
)
set /A CNT=!CNT!+1
if !CNT!==3 (
echo.AHO%%S>>%FILENAME%
) else (
echo.%%S>>%FILENAME%
)
)
pause
実例2:テキストファイルを読み込んで、3の倍数の行だけ行頭に「AHO」を追記
@echo off
setlocal enabledelayedexpansion
SET FILE_IN=test.txt
for /f "tokens=1* delims=: eol=" %%R in ('findstr /n "^" %FILE_IN%') do (
echo.ROW=%%R
if %%R==1 (
call>%FILE_IN%
)
set /A AMARI=%%R%%3
if !AMARI!==0 (
echo.AHO%%S>>%FILE_IN%
) else (
echo.%%S>>%FILE_IN%
)
)
pause