sed ってなんなの?
あーなんか言語紹介といえばこんなのがあったのでした。sed ってなんなのかという、とてもよくある疑問に対して私なりの回答です。まず実用を考えると、
sed 's/hoge/hage/'
このためだけに存在している言語です。メリットは perl -pe 's/hoge/hage/' より 4byte 短くてすむことだけです。これ以外の機能はスクリプト言語で十分なように思います。たまに勘違いしてる人がいる気がしますが、 y コマンドはカウンタを作るために存在しています。小文字を大文字に変換する、などと考えるとどのような時に使うのか皆目検討もつかず、ドツボにはまることうけあいです。気をつけましょう。ちょうど OOP を犬とか猫で教えるような話に似てるかもしれません。
で、 sed in depth 。 sed とはなにか? 誰がなんと言おうと、 sed は VM です。以下に VM の仕様を示します。
命令セット(レジスタやメモリの移動系)
はい、どう見ても VM です。これ以降の命令はあんまり VM ぽくないので適当に。 :label で label ってラベルを作れて、 b label でそこに飛べます。おおアセンブラぽい。直前のマッチに成功していたらジャンプ、というのが t label でできます。えーとあとは p(rint) とか q(uit) とかはわかるかと。 print がある VM ってめずらしいねというツッコミは却下です。なぜなら ICFPC の UM はあったから。
で、とにかく重要なのは、普段 s/hoge/hige/ とかでやってる処理はレジスタでの処理だということです。で、 CISC なアセンブラ書く人はわかってると思いますが、レジスタなんつーものは極めて短命です。 sed VM でも例外じゃないです。というかなんせ、1個しかレジスタが無いのですから、その大事度合いは x86 の 6 倍くらいになると予想されます。そこでメモリ領域があるのですが、恐ろしいことにこれも 1 つしかありません。しかし幸い、レジスタもメモリも文字列領域なので、基本的に無限長です。そこで、 1 つの空間を複数にわけて活用することになります。
そこまでわかっちゃえば、後は適当にメモリ内の 1行目はあの情報、2行目はあの情報、というような約束を決めて、毎回メモリから全データコピー→適当に正規表現で必要な情報を切り出す→処理→メモリのトップに返す→またメモリから拾ってる→とりあえずトップに返した情報を正しい位置に置く→メモリに返す、というサイクルを繰り返せば、とりあえず割と普通にプログラムができます。あとはエルフヘッダの知識と無駄に消費するための時間、ちょっとした工夫くらいがあればコンパイラも書けます!
で、えーと一応お約束なので。
$ { i Hello world! }
どっちも説明してねー機能だった…