Help us understand the problem. What is going on with this article?

今さらDOSコマンドバッチ入門2015

More than 3 years have passed since last update.

DOSコマンドによるバッチファイルの使い方まとめ。普段は使わないけれど、いざという時に使えるとちょっと便利でもある。ただ、改めて文法を調べてみると、むしろ前衛的と言えるぐらいカオスでもあった…。

追記
結論として、DOSコマンドでのファイルの読み書きはオススメしません。文字コードが原則Shift_JISのみなのと、ファイル中に制御記号が含まれていると想定外の処理をすることがあるためです。WSH(VBScript、JScript)やPowerShellのほうが適しています。

churippu_s.png 基本1:set(変数に値をセット)

 ・変数へ代入 set NAME=太郎
 ・変数を参照 echo.%NAME%
 ・数式を代入 set /A NUM=1+2+3+4
/Aオプションにより、右辺が数式として評価されます。またechoは画面出力ですが、上の例で%NAME%が空文字だとエラーメッセージが出てしまいます。それを防ぐためにecho.と、ドットを付けるようにしましょう。

test.bat
@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 を宣言します。遅延環境変数と呼ばれてるようです。そして、変数を参照する時には!変数!のように、感嘆符で囲みます。

test.bat
@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

追記
ただし問題点として、遅延環境変数が有効の場合、文字変数中の感嘆符が制御記号扱いとなり感嘆符が消失してしまうので要注意です。

churippu_s.png 基本2:エスケープ

リダイレクト記号<>などの制御文字を通常の文字として扱うには、その直前にエスケープ記号^を置きます。ただし、setecho処理ではその都度、エスケープ記号が消費される(?)ため、余分に記述しておく必要があるようです…。が、遅延環境変数ではその必要はないようです…。カオスな仕様やね…。

test.bat
@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

yotsuba_s.jpg 実例1:テキストファイルを読み込んで、3行目だけ行頭に「AHO」を追記

test.bat
@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

yotsuba_s.jpg 実例2:テキストファイルを読み込んで、3の倍数の行だけ行頭に「AHO」を追記

test.bat
@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
Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away