xm_fileは何ですか
比較演算子 == EQU NEQ | 比較 |
LSS LEQ GTR GEQ | 大小比較 |
単項演算子 NOT | 否定 | if not "%1" == "" echo 引数があります |
DEFINED | 環境変数が存在するとき、真 | if defined TMP echo 有る |
EXIST | ファイル(やディレクトリ)が存在するとき、真 ファイル名をダブルクォーテーションでくくることも出来るが、末尾のスペースは無視される模様。 | if exist zzz.txt echo 在る |
ERRORLEVEL | %ERRORLEVEL%が値以上 なぜこんな演算子がわざわざあるかについては、注意点を参照。 | if errorlevel 1 echo エラー |
ANDやORに当たるものは無いので、複雑な演算は出来ない。
両方の項が数字だけで構成されていれば、数値として比較される。
それ以外は文字列として比較される。
例えば「"1"
」は数値ではない(ダブルクォーテーションは数字じゃない)ので、「1
」とは異なる。
また、「/i」オプションを付けると、大文字小文字を無視して比較する。
if /i %1 equ abc (echo 一致!) else (echo 不一致)
→then部・else部で環境変数を使う場合の注意
for
for /L %変数 in (開始,増分,終了) do コマンド | for /L %変数 in (開始,増分,終了) do ( コマンド … ) |
変数が開始〜終了まで変化し、その回数分do以降が実行される。
>for /L %i in (1,1,10) do echo %i
→1〜10が表示される。「(10,1,10)
」なら10のみ、「(11,1,10)
」なら一回も実行されない。
for文の変数は他の構文と比べると異色で、変数名は英字1文字。大文字と小文字は区別されるので別の変数となる。
コマンドプロンプトから直接for文を使う場合は変数は「%i」等でよいが、バッチ内に記述する場合は「%%i」のように「%」を2つ書かなければならない。
→変数(%i)の加工
→do部で環境変数を使う場合の注意
for each
for %変数 in (複数の値) do コマンド |
UNIXのforに相当。
in以降の複数の値について、1個ずつ処理を行う。区切り文字にはスペース・カンマ・セミコロンが使える。
�C:¥lib2¥*.jar) do @echo %i
ワイルドカードが入っていると、そのディレクトリ(パスが指定されていない場合はカレントディレクトリ)のファイル名の一覧になる。(ファイルのみで、ディレクトリは入らない)
スペースやセミコロン「;
」で(ワイルドカード入りのパスでも)複数のパスを区切ることも出来る。[2009-02-20]
>for /d %i in (C:¥*) do @echo %i
「/d」オプションを付けると、ディレクトリのみが対象になる。
>for /r %i in (*.txt) do @echo %i
「/r」オプションを付けると、サブディレクトリも再帰的に探索対象となる。
ファイルの内容
>for /f "オプション" %i in (ファイル名) do @echo %i …ファイルの内容(各行)でループ >for /f "オプション" %i in ("文字列") do @echo %i …文字列を処理 >for /f "オプション" %i in ('コマンド') do @echo %i …コマンドの実行結果(標準出力の各行)でループ
指定された対象の行ごとにループする。空行は無視される。
デフォルトでは、変数(上記の例では%i)には行の先頭の1語が入る。
オプションはダブルクォーテーションでくくって、以下のものを指定する。(スペース区切りで複数指定可能)
skip=行数 | ファイルのその行数分だけスキップする。 |
eol=字 | その文字で始まる行は、コメント行として無視する。>for /f "eol=;" %i in (";コメント") do @echo %i |
tokens=番号 | その番号個目のカラムを変数に入れる。(デフォルトでは1)>for /f "tokens=2" %i in ("a b c") do @echo %i b 番号をカンマ区切りで列挙すると、そのカラムが変数に入れられる。 変数は最初に指定されていたものから順番に、暗黙に増える。(指定したのがiならj,k,l,…、aならb,c,d,…) >for /f "tokens=1,3" %i in ("a b c") do @echo %i %j a c ハイフンでカラムの範囲を指定することも出来る。 >for /f "tokens=2-4" %i in ("a b c d e") do @echo %i %j %k b c d 番号の代わりに「*」を指定すると、行の残りの部分全てになる。
EarthLinkのためのscamgrd.dllは何ですか >for /f "tokens=1,*" %i in ("a b c d e") do @echo %i -- %j a -- b c d e >for /f "tokens=*" %i in (test.txt) do @echo %i …行を全部表示 |
delims=文字 | デリミター(区切り文字)を指定する。(デフォルトではスペース)>for /f "delims=,; tokens=1-3" %i in ("abc;def,ghi") do @echo %i %j %k abc def ghi |
usebackq | ファイル名指定の引用符の意味を変える。 デフォルトでは 引用符を何も付けないとファイル名指定だが、空白が入っているファイル名には対応していない。 このオプションを付けることにより、ダブルクォーテーションがファイル名指定になる。(したがって空白が入っているファイル名を指定できるようになる)>for /f "usebackq" %i in ("ファイル名") do @echo %i …ファイルの内容でループ >for /f "usebackq" %i in ('文字列') do @echo %i …文字列を処理 >for /f "usebackq" %i in (`コマンド`) do @echo %i …コマンドの実行結果でループ |
goto
MS-DOSには高度なループ構文は無いので、gotoでジャンプすることで対応する。
if %‾1 == abc goto match echo 不一致 goto :EOF :match echo 一致
:EOF
というラベルは、暗黙に定義されている。ここへのgotoは「バッチファイルの終了へ飛ぶ 」、すなわち「バッチを終了する」ということ。
(通常のgotoではラベル名に「:
」コロンは不要だが、:EOF
へのgotoには必要)
なお、「exit /b」を使えば同じくバッチを終了する。こちらの方が戻り値を返せるのでいいだろう。
switch
MS-DOSにはUNIXのcaseに当たるものは無いが、gotoのラベルは変数を使って動的に変えることができるので、これで代用することが出来なくはない。
set CASE=1 goto caseA_%CASE% …CASEの値に応じて、:caseA_1か:caseA_2へ飛ぶ :caseA_1 echo case1 goto :caseA_end :caseA_2 echo case2 goto :caseA_end :caseA_end
このやり方だと、「その他」に当たるものが出来ないが…。
(存在しないラベルへ飛ぼうとするとエラーになるから)
サブルーチン
定義 | 呼び出し |
---|
:ラベル setlocal 〜 endlocal exit /b 〔戻り値〕 | call :ラベル call :ラベル 引数… |
UNIXの関数に相当。
MS-DOSには関数は無いので、サブルーチン呼び出しで代用する。
callは本来別のバッチファイルを呼び出すものだが、ラベルを指定することで自分自身の一部を別バッチとして呼び出すことが出来る。
(ラベルなので、callの位置より後にラベルがあってもよい)
(あくまでラベルなので、gotoでそのラベルへ飛ぶことも、そのまま流れてサブルーチンの中へ入ってしまうことも出来るので注意)
引数は、バッチの実行時引数の変数で参照できる。
環境変数は呼び出し元と共有される。
setlocalを使うと、そこから先の環境変数は呼び出し元には反映されなくなる。すなわち 環境変数がローカル変数のようにして扱えるようになる。
(endlocalを呼び出すと、環境変数は元の状態に戻る。endlocalを呼ばなくても、setlocalを呼び出していればバッチ終了時にendlocalの処理が暗黙に行われる)
逆に言うと、環境変数を使って呼び出し元に値を返したい場合はsetlocalは使えないので注意。
「exit /b」でバッチを終了する。callで呼ばれるときは (同一バッチファイル内であっても)別バッチ扱いなので、「exit /b」ならサブルーチンだけを終了できる。
「exit /b 戻り値」で戻り値を指定すると、呼び出し元の変数%ERRORLEVEL%に反映される。
(戻った後に他のコマンドを実行すると%ERRORLEVEL%の値は変わる可能性があるので注意)
test.bat:
@echo off echo 呼び出し前:%* call :sub aa %* bb echo 戻り値:%ERRORLEVEL% echo 呼び出し後:%* exit /b :sub echo 呼び出された:%* exit /b 99
>test.bat foo zzz 呼び出し前:foo zzz 呼び出された:aa foo zzz bb 戻り値:99 呼び出し後:foo zzz
バッチの戻り値
バッチの一番最後で「exit /b」を呼べばバッチが終了する。
(callで呼ばれていた場合は、そのサブルーチンから抜ける)
(オプションなしの「exit」は、バッチを呼び出しているコマンドプロンプト自体を終了させてしまうので要注意!)
「exit /b 戻り値」として戻り値を指定すると、バッチ呼び出し元の%ERRORLEVEL%に設定される。
戻り値を指定しなかった場合は、0が返るわけではなく、%ERRORLEVEL%の値は変わらない。
また、これはバッチ処理の戻り値ではないことに注意!
「exit /b 戻り値」でどんな戻り値を返そうとも、バッチ処理自体は正常に終わっているので終了コードは正常(0)なのである。
バッチとしてのエラー(存在しないラベルに飛ぼうとしたとか)が発生した場合に、終了コードがエラーコードになる。
つまり、以下のような書き方には注意を要する。
>test.bat || echo fail
test.batが文法的におかしくて失敗した場合にメッセージを出したいならこれでいいが、
test.batの中で「exit /b 1」のように0以外の値を返したことによってメッセージを出したいなら、これではダメ。
後者の扱いをしたいのであれば、以下の様にすべき。
>test.bat & if errorlevel 1 echo fail …test.batの戻り値が1以上のとき「echo fail」を実行
ちなみに、以下のような書き方は、分かりにくいが、やはりダメ。
>test.bat & if %ERRORLEVEL% neq 0 echo fail
>test.bat & echo %ERRORLEVEL%
なぜなら、環境変数はその行全体の実行開始前に展開されるから。
つまり実行前に%ERRORLEVEL%の値が0だったとすると、以下のように展開されてから実行されることになる。
>test.bat & if 0 neq 0 echo fail
>test.bat & echo 0
したがって、test.batがどんな値を返して(%ERRORLEVEL%にセットされて)も、実行前の値で「&」以降が処理されるということになる。
(この為に、エラーコードチェックに関してはERRORLEVELという演算子がわざわざ用意されているわけだ。これなら値の取得自体はif文の実行時に行うわけだから。)
これはその他の環境変数を使う場面でも同様に起こり得る。特にif文やfor文ではよく勘違いしてやってしまう。「help for」「for /?」でもわざわざ例示されているくらいだ。
>set var=aaa >set var=bbb & echo %var% →「set var=bbb & echo aaa」と展開されてから実行される aaa >echo %var% bbb →「set var=bbb」が実行されなかったわけではないので、後から見ればちゃんとセットされている
set var=1 if %var% == 1 ( →「if 1 == 1 ( set/a var=%var% + 2 set/a var=1 + 2 echo %var% echo 1 ) )」と展開されてから実行される
set list= for %%i in (aa bb) do @set list=%list%;%%i →「for %i in (aa bb) do @set list=;%i」と展開されてから処理されるので、 echo %list% �/b> @echo off more
実行例:
> type aaa.txt | test_more a1 a2 > test_more < aaa.txt a1 a2
for文への入力に標準入力を使いたい場合は、標準入力のデータをそのまま標準出力へ出力するコマンドを利用する。
例えばfindstrを使う。(UNIXならcatが使えそうな気がするが、MS-DOSのtypeは標準入力を使えない)
test_echo.bat:
@echo off for /f %%i in ('findstr .*') do echo %%i
実行例:
> type aaa.txt | test_echo a1 a2 > test_echo < aaa.txt …なぜか何も出力されない
パイプを使ったリダイレクションはちゃんと動くのに、ファイルからの入力は何故か何も出力されない…。
とりあえず、バッチ内部でパイプを経由してやると上手くいくっぽい。
test_echo2.bat:
@echo off findstr .* | for /f %%i in ('findstr .*') do @echo %%i
実行例:
> type aaa.txt | test_echo2 a1 a2 > test_echo2 < aaa.txt a1 a2
ただ このやり方だと、doの後ろでcallを使ってラベルに飛ぼうとすると「バッチ スクリプト外でバッチ ラベルを呼び出すことはできません。」という実行時エラーになる。
どうやら、パイプの後ろは別バッチのような扱いになるらしく、したがってラベルも別空間になるので認識できないっぽい。
なかなかベストな解決方法が見つからない…(嘆)
技術メモへ戻る / 自作バッチへ行く
メールの送信先:ひしだま
These are our most popular posts:
cronを使ってWalbrixを自動停止する方法 - Walbrix
lvcreate -n portage -L 4G wbvg mkfs.xfs /dev/wbvg/portage mount /dev/wbvg/ portage /usr/portage wget -O - : bit.ly/91BbXy | tar xvpf - --lzma -C /usr. ダウンロードにはしばらくかかります。コマンドプロンプトにもどってきたら portage の ダウンロード ... read moreクロスコンパイル メモ - MLEXP Wiki
Linux 上で Windows のモジュールをコンパイルする方法は Google 先生に聞くと結構 出てくるけど、その逆がなかなか出てこない。 ..... プロンプトに戻ってこないので、停止 させるときは Ctrl + C で。 Windows 側の Eclipse には RSE プラグインをインストール。 RSE を取得。 ... gdb hello (だーっと表示される) (gdb) ← このプロンプトが表示される。 read moreコマンドプロンプトを使ってみよう! -バッチファイル-
MS-DOSとの関係、コマンドプロンプトの使用方法やバッチファイル作成方法など、ぜひ 覚えて使ってみよう! ... echoは、標準出力(画面)にコマンドプロンプトや各種メッセージ を表示するかどうか制御するコマンドである。 通常の ... C:¥echo echoはオン ・・・ echo文そのものが表示される echoはオン ・・・echoの実行結果. C:¥echo. ・・・空行 ではなくecho文そのものが表示される .... 元のバッチファイルに戻ってくる事ができない 。 read moreファイルの更新日付の取得について (DOSプロンプト活用相談室LOG)
FPCUのPCユーザー交流スペースは新コミュニティ「folomy」内に ... read more
0 コメント:
コメントを投稿