Home / Windows:バッチファイル

HELP が貧弱なのでメモしておかないと使い難い...
2012-1-15, 2012-11-11 少し手直し。

ファイルパス

パラメータがファイルパスならば、は、色々と分解なんかが出来る。言い換えると、パラメータを渡す時にしか出来ない。そう言う意味でサブルーチンは重宝すると思う。
以下、call /? の抜粋。

    %~1         - すべての引用句 (") を削除して、%1 を展開します。
    %~f1        - %1 を完全修飾パス名に展開します。
    %~d1        - %1 をドライブ文字だけに展開します。
    %~p1        - %1 をパスだけに展開します。
    %~n1        - %1 をファイル名だけに展開します。
    %~x1        - %1 をファイル拡張子だけに展開します。
    %~s1        - 展開されたパスは、短い名前だけを含みます。
    %~a1        - %1 をファイル属性に展開します。
    %~t1        - %1 をファイルの日付/時刻に展開します。
    %~z1        - %1 をファイルのサイズに展開します。
    %~$PATH:1   - PATH 環境変数に指定されているディレクトリを検索し、
                  最初に見つかった完全修飾名に %1 を展開します。
                  環境変数名が定義されていない場合、または検索してもファイルが
                  見つからなかった場合は、この修飾子を指定すると空の文字列に
                  展開されます。

修飾子を組み合わせて、複合結果を得ることもできます:

    %~dp1       - %1 をドライブ文字とパスだけに展開します。
    %~nx1       - %1 をファイル名と拡張子だけに展開します。
    %~dp$PATH:1 - PATH 環境変数に指定されているディレクトリを
                  検索して %1 を探し、最初に見つかったファイル
                  のドライブ文字とパスだけに展開します。
    %~ftza1     - %1 を DIR の出力行のように展開します。

これら幾つかを Windows 2000 で確かめた処、
日付は西暦の下2桁が表示され、時刻の秒は付かない。ex. 11/09/19 22:32
ファイルサイズには3桁毎の区切りは入らない。

なお、ファイルパスに限らず、空白を含むパラメータはダブルクォートで囲まれて来るので、文字列を結合するような処理には %~n でダブルクォートを削除してから結合しないといけない。

バッチファイル内にサブルーチンを書く

パラメータにファイルパスを渡し、サブルーチンでファイル名だけを表示する例。

@echo off
call :SUB %1
goto :END

:SUB
    echo %~n1
    exit /b

:END

・call :サブルーチン と書く
・サブルーチンの戻りは exit に /b を付ける。

なお、GOTO /? を見ると :EOF が暗黙で定義されているようなので、次のように END ラベルは省略出来る(コマンド拡張機能を有効にしていれば、と書かれているが、多くの場合、有効になっているだろう)。

@echo off
call :SUB %1
goto :EOF

:SUB
    echo %~n1
    exit /b

また、exit /b で終わってもいいだろう。

@echo off
call :SUB %1
exit /b

:SUB
    echo %~n1
    exit /b

call

call :サブルーチン と書くのだが、ここでコロンを付けないとファイル名と思われてしまう。
では、上の例で SUB バッチを用意して call SUB と書いて実行すれば良いか?
駄目、失敗する。
どうも拡張子を見ている風で、call はコマンドプロセッサを介しているようだ。 start /wait と似ている。
因みに call calc と書けば電卓が起動し、その終わりを待つ。
悪戯で書くとこんな感じ↓

@echo off
call CALC %1
goto :EOF

:CALC
    echo %~n1
    exit /b

それでは

@echo off
call :CALL %1
goto :EOF

:CALL
    echo %~n1
    exit /b

... これは問題無い。
紛らわしいので GOSUB と命名した方が良いんじゃないか...

重複したラベル

警告は出ない。前方で最初に見つけたラベルから処理するようだ。

@echo off
    goto :SUB
    echo ---
:SUB
    pause
    call :SUB
    goto :EOF

:SUB
    echo AAA
    exit /b
:SUB
    echo BBB
    exit /b

続行するには何かキーを押してください . . .
AAA

となる。ラベルを多く使う場合は注意を要する。

動的、日本語なラベル

引数でサブルーチン名を指定可能。日本語もOK。英字は大小文字区別無し。
簡単なテーブル、微妙に異なる処理が必要なら、後述の for より簡単になる。

@echo off
    call :%1
    echo %errorlevel%
    goto :EOF
:米国
    echo US
    exit /b 1
:日本
    echo Japan
    exit /b 2
:Japan
    echo 日本
    exit /b 3

テキストファイルを1行ずつ読み込み処理する

何でこれが for に組み込まれるのか?と不満だが、致し方無い...

FOR /F "eol=; tokens=2,3* delims=, " %i in (myfile.txt) do (
    @echo %i %j %k
)

因みに、ファイル名にワイルドカードは使えないっぽい... orz
UNIX系と違い、コマンド側でワイルドカード展開する方針にしているからこんな事になる。カトラーは UNIX が嫌いだったらしいが、コマンドラインを疎かにしたら駄目だよ。認めてあげない。

尤も、ワイルドカード展開する呼び出しループを書けば済むとは思うが。

なお、CSV形式ファイルを読む例を書いているが、欄がダブルクォートで囲まれていようがいまいが、お構い無しに区切り文字で欄分解する。Windows バッチ全般に言えるが、子供騙しの玩具でしかない。

FOR /F への入力をパラメータとする

ヘルプに明記されていないが、文字列と同じくダブルクオートで囲むみたい。

FOR /F "tokens=1,2 delims=," %%i in ("%~1") do (
    echo %1
    echo %%i%%j
)

数値演算(整数のみ)

素直に外部コマンドを追加すればと思うのだが、奇天烈な事に set を拡張してある。
/A で式解釈となるそうな。変数を扱うからこれにしたんだろう。
ヘルプには「論理演算子またはモジュール演算子を使う場合は、式文字列を引用符で囲む」とあるが、モジュール? %演算子か? 四の五の言わずに引用符で囲むべし。

@echo off
set /A "hoge+=%1"
echo %hoge%

strtol関数の如く、0x や 0付き8進数を解釈する。浮動小数点は駄目。
電卓が標準装備なんだし、ある程度のキーシーケンスとやらを受け付けるんだから、そっちを拡張した方が良いだろうに... 全くもって MS の拡張のやり方は滅茶苦茶。

エスケープ

サーカム フレックス (^)を使う。古い SDK 中のバッチファイルで知った。
(漢字で誤魔化せるが)リダイレクト記号(<や>)を echo 表示するにはこんな感じ。

@echo off
echo Usage: %0 ^<hoge^>

Home / Windows:バッチファイル

© 2008 usskim    http://usskim.web.fc2.com/
inserted by FC2 system