CMD

head コマンド再び

CMD

昨日書いたように、for 文中での環境変数の直近値の参照方法はいろいろある。そこで、 以前あきらめた head コマンドの for /f での実現をやってみた。ただし、空行はスキップされると言う for /f の仕様だけは我慢することになる。一方、副産物だが、do ( )…

複合文中での環境変数参照

CMD

if や for や ( ) の内部での % での環境変数置換は最初に行われるため、複合文内部で環境変数の値を変更してもその新しい値を参照しにくい。この参照の仕方を整理しておく。(1) 遅延環境変数展開を使う これが一番簡単であるが、デメリットとしては、% で展…

for文とgoto文

CMD

for 文から goto 文で抜け出ることが出来る。 が、抜け出なくても goto しただけで、for 文の機能が無効になるようだ。 @echo off for /l %%I in (1,1,5) do ( if %%I==3 goto x echo A %%I :X echo B %%I ) を実行すると、 A 1 B 1 A 2 B 2 B %Iと、制御変…

コマンド実行時のエコー表示の謎

CMD

バッチススクリプトでは通常先頭で、@echo off するので、デバッグ時以外はコマンド実行のエコーを目にすることはあまり無い。 最近気づいたのだが、以下の一部のオプションなどについて、小文字で入力しても大文字になってエコー表示される(WXPで確認)。 if…

【続】環境変数に改行文字をセット

CMD

前回からの続き。 set X=echo 1^ echo 2 という風に環境変数AAにセットした2行の命令をそれぞれ実行するにはどうするか。前回書いたように、 %X% !X! とも駄目である。 if や for や ( ) の構文解析が % による環境変数置換に先立って行われることを思い出し…

環境変数に改行文字をセット

CMD

^ による行の継続を試している時に、環境変数に改行を含んだ文字列をセットできることに気づいた。 set AA=123^ 456 のように間に空行をはさむと、AA に 123 改行 456 がセットされる。 set AAA=123^ 456^ 789 のようにすれば何行でも入る。ただし、この値を…

findstrコマンドの使い方

CMD

findstr コマンドに、 /L 検索文字列をリテラルとして使用します。 /R 検索文字列を正規表現として使用します。 /C:文字列 指定された文字列をリテラル検索文字列として使用します。 というオプションがあるが、/L の「リテラル」と /C の「リテラル」の意味…

tail コマンドの作成

CMD

昨日、の続き。 昨日書いた、:getline サブルーチンだが、「空行とEOFを区別できない」という set /p コマンドの仕様からああいう機能になってしまった。しかし、実際 tail コマンドを書こうとするとどうも使いにくい。そこで、まず普通の1行入力機能を持っ…

head コマンドその後

CMD

以前、head コマンドについて書いたが、ふと思い立って続編の tail コマンドを書いてみようかと思った。 前回のスクリプトは行入力と head のメインロジックが混じっており、ちょっと汚いので1行入力部分を :getline というサブルーチンにしてみた。:getline…

^ によるquoteについて

CMD

昨日の記事において、 call echo %%%A%%% と書いたが、この時、^ で % をquote出来るのでは?と思って、 call echo ^%%A%^% としてみた(sh だと、eval echo \$$A に相当)ところ、表示されるのは、A だけである。 どうも、^ によるquote処理より、%による展開…

CALL命令の謎

CMD

10月29日記事において、 また、call バッチファイル名 や call :ラベル名 だけではなく、call CMDビルトイン>コマンド や call 実行ファイル名、call 文書ファイル名 等としても、コマンドプロンプトから直接ファイル名などを入れたのと同じように実行されま…

lsコマンドの作成(2)

CMD

前回の続き。 オプション解析を含む完成版である。対応オプションは少ないが、自分でよく使うのは、ls (linuxでは ls -vxF にaliasしてある)、ls -l 、ls -ltr くらいなので一応満足。shift が %* に影響を及ぼさないので、%* を使えないのがいつもながらい…

lsコマンドの作成(1)

CMD

headコマンドも放ったらかしだが、lsコマンドを作ってみたい。 現在は、DOSKEYマクロで、 ls=dir $*|findstr/r "^[0-9][0-9][0-9][0-9]" と定義しているが、見ればわかる通りこれは ls -l 相当である。 あと、オプション無し(マルチカラムでファイル名のみ)…

dirコマンドと特殊文字

CMD

10/29に書いた、 あと、dir ^ や dir ^> の動作も謎。よくわからない。 dir ^ だと一部のファイル・ディレクトリだけが表示されるが、どういう条件のものが表示されるのかわからない。 だが、dir ^ →ファイル名にピリオドを含まないものを表示dir ^> →ファイ…

CALL 文パラメータ中の特殊文字

CMD

随分日にちが空いてしまいました。 CALL 文パラメータ中の特殊文字について (1) /? があればヘルプを表示 (2) | があればcallが実行されない (3) または > があれば次の1ワードがバッチスクリプトに渡らない ということのようです。 (註: | の場合はリダイ…

今までの残件は

CMD

今まで、別途調べてみる等としていた事項を整理しておく。(1) 8/15の、環境変数遅延展開と構文解析の整理。これは、一度、8/28:変数置換の順序に書いたが、もう一段の突込みが必要と思っている。(2) 8/19の、ディレクトリの存在チェックが、最後に \ を付け…

head コマンドが作れるか? (4)

CMD

さて、前回までのことはすっぱり忘れよう。思い出すのは、8/8: 【続々】標準入力からの読み取りの回だ。 そこに書いたスクリプトを再掲する。標準入力からの標準出力へのコピーである。(100個連続した空行がないと仮定) スクリプトA: @echo off setlocal ena…

お便りに答えて

CMD

昨日の記事について、 ファンさんからまたコメント*1をいただいた。いつも何か得るところがある。ありがとうございます。 for 文からの途中脱出は、遅延展開を有効にしておいて、サブルーチンからの戻りを判定して goto すれば可能ですよね。 遅延展開を使う…

head コマンドが作れるか? (3)

CMD

昨日書いたように、途中で for を終了させるのは出来なさそうなので、ループをファイルの行数回だけまわるのは止むを得ないとすると、一定回数以上まわったら echo をスキップするようなことを考える。 rem スクリプト5: setlocal set N=0 for /f "delims=" …

head コマンドが作れるか? (2)

CMD

昨日の続き。 for 文の中で行数をカウントできないとすると外でやるしかない。一旦外に出て帰ってくるわけだ。このとき、外でも for 制御変数が有効かどうかを調べてみる。 rem スクリプト1: for /f "delims=" %%A in (test.txt) do call :sub goto :eof :su…

head コマンドが作れるか? (1)

CMD

次なるコマンドとして、head コマンド (unixのhead相当;以下同) を作ろうとしてしばらく苦戦している。 ここに書きながら進めていきたいと思う。まず cat コマンドのサブセットは比較的簡単に出来る。サブセットと言うのは、 (1) オプションなし (2) 標準入…

変数置換の順序

CMD

変数の置換や構文解析の順序だが、いろいろやってみた結果次のようである。 (1) 環境変数の置換、引数の置換が同順序で最初 (2) if/for/( ) 等の構造を持った文の構文解析、およびリダイレクトの判断等が同順序 (3) for制御変数の置換 (4) 環境変数遅延展開…

スクリプト中のコメント

CMD

8/15: 【続】スクリプト中の未定義環境変数の謎で、 >「スクリプト中の任意の場所に、%" と "%で囲んだコメントが書ける」ということだ。 と書いたが、ちょっと間違っていた。%" "% で囲むというよりは、% % で囲まれていればいい。その時テストした際には…

【続々々】ディレクトリかどうかの判断

CMD

昨日の記事に対し、 >私は、dir "対象" /a:d してみて errorlevel を見ます。 NUL に頼るより確実では? というコメント*1を頂いた。DOSの時代から、ディレクトリのチェックは\NULを使ってやるものという先入観を持っていた。 いまや、dirコマンドにも/adオ…

【続々】ディレクトリかどうかの判断

CMD

体調が悪い(先週金?土は38度の熱でうなりながら寝ていた)ので、小ネタ。 7/28:ディレクトリかどうかの判断で、パスが " " で囲まれると、if exist によるる \NULの存在チェックがうまく行かないことに対する対策を書いた。>(1) for制御変数にいれ、ショー…

隠し環境変数の謎

CMD

昨日書いた %" "% のコメントに機能に絡んで、" " に囲まれた環境変数名が使えないものかやってみた。が、 set "AA"=123 環境変数 AA が定義されていません となる。つまり、 set AA と同じ結果になる。ついでに、 set ""=123 をやってみたところ、set と同…

【続】スクリプト中の未定義環境変数の謎

CMD

昨日の続きである。 環境変数名に空白が含まれても良いとか、数字でも良いとか書いたが、日本語ももちろんOKのようである。 またいくつかの記号も使える。なんと % も使える。スクリプト中では、% は %% と書くので、以下のようになる。 setlocal enabledela…

スクリプト中の未定義環境変数の謎

CMD

昨日、スクリプト中での未定義環境変数の振る舞いが良くわからないと書いた。 実際 set _= if defined _ if not "%_%" == "%_: =%" set _="%_%"</b> と書いて実行すると、 コマンドの構文が誤っています。 if defined _ if not "" == " =_" となってしまう。なぜ…

お便りに応えて

CMD

コメント*1にはコメントでと思いましたが、本文のネタが無いので本文でお返事します。>バッチコマンドスクリプトで個人用ツールをちょくちょく組んでいるものです。長いものだと 2000行近くなることもあります。これには驚きました。BATにそのレベルのもの…

WHICHコマンド (6) 〜最後〜

CMD

最終回は残りの部分。1回目の仕様で書いた、 (5) PATHをサーチして見つけた最初の実行ファイルのフルパスを環境変数「 _ 」にセットする の部分であるが、最後なので全文を掲載する。例によってインデントは2バイト空白なのでコピーペーストする人は注意。PA…