コマンドラインもオブジェクト

かなり今更な話題だが。


私はコマンドプロンプトを起動してコマンドラインで作業する、ということが少なくはない。いくつかの日記からも想像つくかもしれない。
たとえば、VisualStudio が起動していない状態からプロジェクトをビルドしようとした場合、コマンドプロンプトを立ち上げて devenv project.sln /rebuild Release などとタイプするほうである。
cmd.exe は command.com と比べるとだいぶ使いやすくはなっているが、Windows 標準環境だとコマンドラインからいろいろと操作するにはコマンドラインで動くユーティリティソフトの充実がある程度必要になってしまうし、そもそも cmd.exe では機能的に満足しない人も多いので DOS のころからオリジナルのシェルプログラムや、UNIX 系の OS のシェルプログラムを Windows にもってきたものが活用されていたりする。
そういった従来からのコマンドラインツールは、基本的にコンソールで動作するテキストベースのツールであり、たとえば入力を各行毎に並び替える sort や、ソート済みの入力をグループ化する uniq、特定の内容を含む行を抽出する grep といったほかに、各行の指定カラム目から指定カラム目までを切り出したり、正規表現などを利用して特定のパターンを抜き出すようなものまで多様にある。それらは単一では単純な機能しかもたないが、パイプライン処理を通して組みあわせることでさまざまな機能を発揮する。
しかし、最近…というほど最近ではないのだが、シェルプログラムおよびコンソールでやり取りされる情報を、テキストからオブジェクトへと変化させているものがある。テキストからオブジェクトへ変化することで、コマンドラインユーティリティはかなり高性能化し、テキスト処理や文字列操作にまつわる様々なトラブルや制約から解き放たれている。
たとえば、dir コマンドや ls コマンドはファイルの一覧を表示するツールではなく、ファイル情報オブジェクトを列挙するコマンドとなる。つまり、dir コマンドの出力は .NET でいう System.IO.FileSystemInfo[] なのである。

C:\WINDOWS> dir
(略)
2004/08/05  21:00            65,954 大草原の風.bmp
2004/08/05  21:00            17,062 珈琲カップ.bmp
2004/08/05  21:00            16,730 羽毛.bmp
2004/08/05  21:00            26,680 隅田川.bmp
             104 個のファイル           6,354,759 バイト

何も変わってないじゃないかと思われるだろうが、実は System.IO.FileSystemInfo クラスの report の設定として "{0:yyyy/MM/DD hh:mm} {1,17N} {2}", .LastWriteTime, .Size, .Name というようなパラメータと、report-footer としてファイル数とその合計バイト数をする設定になっているだけなのである。*1
ここから、ファイルサイズが 200KB を超えるものだけを抽出したいと考えた場合、従来のテキストベースの処理ではファイルサイズのカラム位置を調べて切り出したりソートしたり、数値として扱えるユーティリティで比較をしたりするところだが、*2ファイルサイズが20桁あるファイルが含まれていて、そのファイルだけ切り出しが失敗していたりする、みたいなトラブルを抱えがちだ。*3
オブジェクトな世界では、dir コマンドの出力は FileInfo なので、そのファイルサイズを示す Size プロパティが 200KB より大きなものだけを取り出せばよいことになる、つまり…、

C:\WINDOWS> dir | pick .Size > 204800
2004/08/05  21:00         1,025,536 explorer.exe
2005/05/03  23:50           202,579 iis6.log
1998/11/11  20:35           306,688 IsUn0411.exe
2004/09/28  20:40           223,427 orun32.isu
2005/01/14  21:33           237,688 setupact.log
2005/01/14  21:34           935,681 setuplog.txt
2005/05/11  00:25           404,956 WindowsUpdate.log
2004/08/05  21:00           264,576 winhelp.exe
2004/08/05  21:00           275,968 winhlp32.exe
2005/05/03  23:50           316,640 WMSysPr9.prx
              10 個のファイル           4,193,739 バイト

pick コマンドは入力オブジェクトに対して、指定した式が成立するものだけを抽出するコマンドで、ここでは Size プロパティが 200KB 以上であること確認する式を指定している。出力は篩いをかけられた FileInfo[] であるため、何も指定をしないときと同じレポーターによって 200KB 以上のファイル数と、その総計バイト数が出力にあらわれている。
当然だが、ファイルサイズの桁位置を間違えたり、ファイルの出現順序が変化したり、出力されるフォーマットが変化するということはありえないわけである。


このようなシェルの1つとして、次期 Windows で採用される MSH(Monard) が、http://beta.microsoft.com/ から試用可能となっているが、残念ながら、まだベータ版であることや、.NET Framework 2.0 beta 上でしか動作しないなどなど、試用・評価の粋をでることができない。
なお、前述の内容は MSH を利用したものではなく、MSH はもうちょっと複雑ぎみになっているが、高性能であることには変わりない。

そういえば

週1ぐらいで覗いている id:higepon さんところの OS のコマンドラインはどうなんだろうか?(自分で試せよ、というのは言わないで)

*1:本当は、それだけじゃないなりたたないんだけど割愛

*2:数値は文字並びでも昇順なので、ファイルサイズの位置で降順にソートすれば 200KB 未満のファイルが出現するまで垂れ流すだけか?

*3:split とかしてれば桁数はあまり影響ないけど、ps | grep | kill で自爆するとかとか