MS-DOSはつきあい長い。 それでもバッチファイルは慣れないのでサンプル置いとく。

コマンドラインでテストしたら、タスクスケジューラで動かすこともあるはず。 バッチ処理内では常にフルパスで書いて扱うことを意識すること。

ただし、あまり深い階層になるとファイル名の長さ制限にひっかかるので注意。

分岐のサンプル(簡単な比較判定)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
echo off

set val=boo

if %val%==boo echo 変数はboo

if not %val% == poo (
    echo 変数はboo
) else (
    echo 変数はpoo
)

pause

動かすとこうなる。

1
2
3
4
Y:\etc\_tmp\20170910>echo off
変数はboo
変数はboo
続行するには何かキーを押してください . . .

分岐のサンプル(比較演算子)

数字を「equ」で比較すると大小を判定し、「==」では文字列比較になる。 equを使うほうがいいのかも。

演算子 内容
equ 等しい
neq 等しくない
gtr より大きい
geq 以上
leq 以下
lss より小さい
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
echo off

set val=1

if %val% equ 10 echo 変数は10

if %val% == 1 (
    echo 変数は1やねん
) else if %val% equ 1 (
    echo 変数は1
) else if %val% equ 2 (
    echo 変数は2
) else if %val% equ 3 (
    echo 変数は3
) else (
    echo 変数はその他
)

pause

動かすとこうなる。

1
2
3
Y:\etc\_tmp\20170910>echo off
変数は1やねん
続行するには何かキーを押してください . . .

分岐のサンプル(errorlevelの判定)

直前に実行したコマンドの結果を判定してみる。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
echo off

type nul > hoge.txt
echo result=%errorlevel%

type
echo result=%errorlevel%


if %errorlevel% equ 10 echo errorlevelは10

if %errorlevel% == 1 (
    echo errorlevelは1
) else if %errorlevel% equ 1 (
    echo errorlevelは1
) else if %errorlevel% equ 2 (
    echo errorlevelは2
) else if %errorlevel% equ 3 (
    echo errorlevelは3
) else (
    echo errorlevelはその他
)

pause

動かすとこうなる。

1
2
3
4
5
6
Y:\etc\_tmp\20170910>echo off
result=0
コマンドの構文が誤っています。
result=1
errorlevelは1
続行するには何かキーを押してください . . .

分岐のサンプル(ifの入れ子))

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
echo off

set val1=2
set val2=1

if %val1% equ 10 echo 変数は10

if %val1% equ 1 (

    if %val2% equ 1 (
        echo 変数は1,1 やねん
    ) else (
        echo 変数は1,other やねん
    )

) else if %val1% equ 2 (

    if %val2% equ 1 (
        echo 変数は2,1 やねん
    ) else (
        echo 変数は2,other やねん
    )

) else (
    echo 変数はその他 やねん
)

pause

動かすとこうなる。

1
2
3
Y:\etc\_tmp\20170910>echo off
変数は2,1 やねん
続行するには何かキーを押してください . . .

ループのサンプル(n回ループ)

1
2
3
4
5
6
7
echo off

for /l %%n in (2,3,29) do (
  echo n = %%n
)

pause

動かすとこうなる。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
Y:\etc\_tmp\20170910>echo off
n = 2
n = 5
n = 8
n = 11
n = 14
n = 17
n = 20
n = 23
n = 26
n = 29
続行するには何かキーを押してください . . .

ループのサンプル(存在するファイルの数だけループ)

実行フォルダ(Y:\etc_tmp\20170910)にファイルがあるとする。

boo.bat foo1.txt foo2.txt foo3.txt

1
2
3
4
5
6
echo off

for %%f in (Y:\etc\_tmp\20170910\*.txt) do (
  echo filename = %%f
)
pause

動かすとこうなる。

1
2
3
4
5
6

Y:\etc\_tmp\20170910>echo off
filename = Y:\etc\_tmp\20170910\foo1.txt
filename = Y:\etc\_tmp\20170910\foo2.txt
filename = Y:\etc\_tmp\20170910\foo3.txt
続行するには何かキーを押してください . . .

ループのサンプル(サブディレクトリに存在するファイルの数だけループ)

実行フォルダにファイルがあるとする。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
Y:\etc\_tmp\20170910>tree /F
Y:.
│  boo.bat
├─foo1
│      foo1.txt
├─foo2
│      foo20.txt
│      foo21.txt
└─foo3
        foo3.txt
1
2
3
4
5
6
echo off

for /r Y:\etc\_tmp\20170910 %%f in (*.txt) do (
  echo filename = %%f
)
pause

動かすとこうなる。

1
2
3
4
5
6
Y:\etc\_tmp\20170910>echo off
filename = Y:\etc\_tmp\20170910\foo1\foo1.txt
filename = Y:\etc\_tmp\20170910\foo2\foo20.txt
filename = Y:\etc\_tmp\20170910\foo2\foo21.txt
filename = Y:\etc\_tmp\20170910\foo3\foo3.txt
続行するには何かキーを押してください . . .

文字列連結のサンプル

普通の変数定義で、ダブルクオートで囲んだ文字列に任意の変数を連結してみる。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
set A1="ほげほげ"
set A2=%A1:"=%

set B1=1
set B2=2

echo A1=%A1%
echo A2=%A2%

echo C="A2:%A2% B1:%B1% B2:%B2%"

pause

動かすとこうなる。

無事に全角文字が混じった文字列に任意の変数が連結できる。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20

C:\Users\nari\Desktop>set A1="ほげほげ"

C:\Users\nari\Desktop>set A2=ほげほげ

C:\Users\nari\Desktop>set B1=1

C:\Users\nari\Desktop>set B2=2

C:\Users\nari\Desktop>echo A1="ほげほげ"
A1="ほげほげ"

C:\Users\nari\Desktop>echo A2=ほげほげ
A2=ほげほげ

C:\Users\nari\Desktop>echo C="A2:ほげほげ B1:1 B2:2"
C="A2:ほげほげ B1:1 B2:2"

C:\Users\nari\Desktop>pause
続行するには何かキーを押してください . . .

文字列連結にループをからめる

連結する文字列をループにからめると、そうはいかない。 例えば、フォルダ名に全角文字がついていて、その中に番号付きのフォルダ名をつけたいときに書いてしまう。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
set A1="ほげほげ"
set A2=%A1:"=%

set P1=0

for /l %%N in (1,1,3) do (
    set /a P1 = P1 + 1
    echo C="A2:%A2% N:%%N P1:%P1% " 
)

pause

動かすとこうなる。 初めて見ると、なんじゃこりゃーって絶叫したくなる。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
C:\Users\nari\Desktop>set A1="ほげほげ"

C:\Users\nari\Desktop>set A2=ほげほげ

C:\Users\nari\Desktop>set P1=0

C:\Users\nari\Desktop>for /L %N in (1 1 3) do (
set /a P1 = P1 + 1
 echo C="A2:ほげほげ N:%N P1:0 "
)

C:\Users\nari\Desktop>(
set /a P1 = P1 + 1
 echo C="A2:ほげほげ N:1 P1:0 "
)
C="A2:ほげほげ N:1 P1:0 "

C:\Users\nari\Desktop>(
set /a P1 = P1 + 1
 echo C="A2:ほげほげ N:2 P1:0 "
)
C="A2:ほげほげ N:2 P1:0 "

C:\Users\nari\Desktop>(
set /a P1 = P1 + 1
 echo C="A2:ほげほげ N:3 P1:0 "
)
C="A2:ほげほげ N:3 P1:0 "

C:\Users\nari\Desktop>pause
続行するには何かキーを押してください . . .

Nは増えてるのに、P1が増えない・・・。 「納期近いのに、なんで思ったとおり動かへんねん!!」ってアセる。

遅延環境変数ってのがある

バッチファイルでは、変数を読み込むタイミングっていうのがある。

遅延環境変数っていう。

こんなんあるからDOSバッチ嫌い。忙しいときに限ってこういうのがポロっと出てきて時間取られる。

うっすら覚えてるけど、どうしてたか思い出せないことが多い。

やり方としては、変数を読み込むタイミングを、「行に入ったとき」ではなく「変数を使うコマンドにたどり着いたとき」にする。

処理の最初におまじない(enabledelayedexpansion)を追加して、変数の書き方を「%」じゃなく「!」で書く。

ここではP1が対象で書き方は、

変更前)echo C=“A2:%A2% N:%%N P1:%P1% "

変更後)echo C=“A2:%A2% N:%%N P1:!P1! "

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
@setlocal enabledelayedexpansion

set A1="ほげほげ"
set A2=%A1:"=%

set P1=0

for /l %%N in (1,1,3) do (
    set /a P1 = P1 + 1
    echo C="A2:%A2% N:%%N P1:!P1! "
)
pause

動かすとこうなる。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

C:\Users\nari\Desktop>set A1="ほげほげ"

C:\Users\nari\Desktop>set A2=ほげほげ

C:\Users\nari\Desktop>set P1=0

C:\Users\nari\Desktop>for /L %N in (1 1 3) do (
set /a P1 = P1 + 1
 echo C="A2:ほげほげ N:%N P1:!P1! "
)

C:\Users\nari\Desktop>(
set /a P1 = P1 + 1
 echo C="A2:ほげほげ N:1 P1:!P1! "
)
C="A2:ほげほげ N:1 P1:1 "

C:\Users\nari\Desktop>(
set /a P1 = P1 + 1
 echo C="A2:ほげほげ N:2 P1:!P1! "
)
C="A2:ほげほげ N:2 P1:2 "

C:\Users\nari\Desktop>(
set /a P1 = P1 + 1
 echo C="A2:ほげほげ N:3 P1:!P1! "
)
C="A2:ほげほげ N:3 P1:3 "

C:\Users\nari\Desktop>pause
続行するには何かキーを押してください . . .

何年かに1回しか出会わないけどこの書き方を思い出すのに、いっつも時間かかる。 ループの中だけでなく、ifの中でも同じ。