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 :サブルーチン と書くのだが、ここでコロンを付けないとファイル名と思われてしまう。
では、上の例で 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
何でこれが for に組み込まれるのか?と不満だが、致し方無い...
FOR /F "eol=; tokens=2,3* delims=, " %i in (myfile.txt) do ( @echo %i %j %k )
因みに、ファイル名にワイルドカードは使えないっぽい... orz
UNIX系と違い、コマンド側でワイルドカード展開する方針にしているからこんな事になる。カトラーは UNIX が嫌いだったらしいが、コマンドラインを疎かにしたら駄目だよ。認めてあげない。
尤も、ワイルドカード展開する呼び出しループを書けば済むとは思うが。
なお、CSV形式ファイルを読む例を書いているが、欄がダブルクォートで囲まれていようがいまいが、お構い無しに区切り文字で欄分解する。Windows バッチ全般に言えるが、子供騙しの玩具でしかない。
ヘルプに明記されていないが、文字列と同じくダブルクオートで囲むみたい。
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^>