Windowsのコマンドプロンプトは変態(一部)

または如何にしてバッチファイルとゴーゴーを踊るか。

Windowsコマンドプロンプトというのがありますな。
Linuxとかでいう、Termみたいなものです。
文字ばっかだし、黒いし。
同じといっても過言ではない。

UNIX系のTermはデフォルトbashtcshなので、
コマンド入力だけでなく、一種の軽量言語としても使える。
強力なシェルスクリプトが作れる。

Windowsにはないのかって?
馬鹿言っちゃいけない。
Windowsには、MS-DOSから連綿と続く、バッチファイルというのがある。
その名の通り、コマンドを並べてバッチ実行するのはもちろん、
ラベルを使った条件分岐や、
引数だって受け取れる。

ちなみに引数は9個受け取れる。
だが、shiftというコマンドを使えば引数をシフトして、10個目以降の引数を見ることが出来る。
試しに以下のバッチファイルで実験してみた。

shift.bat

@echo off

:loop
echo %0 %1 %2 %3 %4 %5 %6 %7 %8 %9
shift
if not "%0"=="" goto loop

コマンドライン

shift.bat 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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100

結果

shift.bat 1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9 10
2 3 4 5 6 7 8 9 10 11
3 4 5 6 7 8 9 10 11 12
4 5 6 7 8 9 10 11 12 13
・・・
96 97 98 99 100
97 98 99 100
98 99 100
99 100
100

100人乗っても、だいじょーぶっ!
何度も言うが、同時に参照できるのは最大10個だ。
そんなに使わないって?

構文については、例えば while 文は存在しないので、
上であげたバッチファイルの例にあるように、ラベルとgoto文を活用する。
なんかBASICぽいぜ。

ちなみにコメント行は以下のように書く。

rem **************************
rem これはコメント行です
rem **************************

BASICと違って、アポストロフィではコメントにならないので注意だ。
ちなみに先頭コロンでも同じ結果になるらしい。
コロン2つという意見が多く見られるのだが、公式ドキュメントには見当たらない。
男は黙って rem に限る。

言語といえば制御構文。
while がないのは上に書いたが、心配ない。
バッチファイルには if と for がある。

whatis.bat

@echo off
if "%1"=="Windows" (
 echo あなたのコンピュータの信頼性を高め、また簡単なものにします。
 echo そして、インターネットにつないだり、想像以上の操作感で、簡単に始めることができます。
 echo その洗練された、やさしいビジュアルデザインは、あなたの指先だけで、
 echo あなたがしたいと思っていることを最大限可能なものにします。
 echo また、そのデジタル メディアツールは、デジタル写真やムービーをシンプルで簡単なものにします。
) else if "%1"=="Mac" (
 echo ビジュアルにはしった、Fuckin OSです。
) else (
 echo それは私の口からは言えません。
)

C:\> whatis Mac
ビジュアルにはしった、Fuckin OSです。

C:\> whatis WindowsMe
それは私の口からは言えません。

if文は、まあ、こんなかんじだ。
わりと普通だ。
詳しくは if /? でヘルプを見ると良い。

しかし、for文は一味違う。
プログラム言語を知っている方なら、for文と聞いて、ループの構文だな、と想像するだろう。
それはその通り。
この文をここまで読んでくださった方は、お土産に、ぜひ以下の構文を覚えて帰ってください。

for %1 in (*.txt) do echo %1

コマンドプロンプトの世界では、%1 は変数である。
*.txtはおなじみワイルドカードで、現在フォルダのテキストファイルにマッチする。
マッチしたそれぞれについて、do 以降のコマンドを実行する。
この構文は結構使える。

たとえば、テキストファイルにnkfコマンドをかける場合、

mkdir after
for %1 in (*.txt) do type %1 | nkf > after\%1

とすれば、afterフォルダに処理後のファイルが保存される。
nkfコマンドなんて無いよ〜、だと?
自分で探せ!
どうせ使えるコマンドはWindowsには入ってない!

だが、for文の力はこんなものではない。
例えば、hoge.txt というファイルを以下の内容で保存する。

ウミ
トル
なめ
まねき

以下のコマンドを実行する

C:\> for /F %1 in (hoge.txt) do @echo %1ネコ
ウミネコ
トルネコ
なめネコ
まねきネコ

なんと、/F オプションをつけるとファイルの中身まで読むのだ。

さらにさらに、

for /F %1 in ('set') do @echo [%1]

のように、コマンドの出力結果まで読み込むことが出来るのだ。
残念ながらこれをどのように利用するのかは思いつかなかった。

なぜならバッチファイル自体は非力だからだ。(ぶっちゃけた)

しかし自作プログラムに渡してやることで、ウマーとなるかもしれない。

この記事のタイトルには、「変態(一部)」、と書いた。
その理由は、この for コマンドである。
ここまで読んでいただければ、for コマンドがただの繰り返し構文ではないな、と気づかれることと思う。
明らかに制御構文の範囲を逸脱しているのだ。
そのさらなる証拠をご紹介する。

以下は、forのヘルプ(for /? )からの引用である。

例を参考にしてください:

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

この例は、myfile.txt の各行を解析します。セミコロンで始まる行を無視し、
各行の 2 番目と 3 番目のトークンを for 本体に渡します。トークンは、カンマ
またはスペースで区切られています。for 本体の文が %i で 2 番目のトーク
を、%j で 3 番目のトークンを取得し、%k で 3 番目以降のすべてのトークンを
取得していることに注意してください。スペースを含むファイル名に対しては、
二重引用符でファイル名を引用する必要があります。この方法で二重引用符を使う
ためには、usebackq オプションを使わなければなりません。使わなければ、二重
引用符はリテラル文字列の定義として解釈され、解析されます。

言ってることの30%もわかりませんが、
とにかく、forはテキスト処理プロセッサですた。
いうなれば、DOS界の AWK です。
FOR って実は開発者3人の頭文字をとってつけてたりしてないですか?

他にも、以下のようなオプションが使えます。

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

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

まあ、便利!
でも絶対に覚えれません。
てか、覚えたくありません。