Grep

Grep

上級

はじめに

地元の図書館で、古い本のコレクションの整理を手伝う仕事に就きました。学生の利用者は、学期末レポートに引用したい、うろ覚えの一節を探していることがよくあります。1冊ずつ最初から最後まで手作業で読む代わりに、それらの本をスキャンして、そうしたうろ覚えの一節を探す小さなツールを作ることにしました。

説明

ファイルから検索文字列に一致する行を探し、一致したすべての行を返します。

Unixのgrepコマンドは、正規表現に一致する行をファイルから探します。 ここでの課題は、固定文字列の検索に対応した簡略版のgrepコマンドを実装することです。

grepコマンドは3つの引数を取ります。

  1. 検索する文字列。
  2. コマンドの動作をカスタマイズするための0個以上のフラグ。
  3. 検索対象となる1つ以上のファイル。

次に、指定されたファイルの内容を(指定された順に)読み込み、検索文字列を含む行を探し、最後に見つかった順にそれらの行を返します。 複数のファイルを検索する場合、一致した各行の先頭にはファイル名とコロン(:)が付きます。

フラグ

grepコマンドは次のフラグに対応しています。

  • -n 出力の各行の先頭に行番号とコロン(:)を付けます。行番号はファイル名の後ろに置きます(ファイル名がある場合)。
  • -l 一致する行を1つ以上含むファイルの名前だけを出力します。
  • -i 大文字と小文字を区別せずに比較して照合します。
  • -v プログラムの動作を反転させ、一致しなかったすべての行を集めます。
  • -x 検索文字列が行全体と一致する行だけを探します。

IOのプロセス

ほかの演習とは異なり、grepは「外界」とやり取りする必要があります。つまり、ファイルの読み込み、システムエラーの処理、stdoutへの出力です。

Leanでは、システムとのやり取りは通常IOモナドの中で行います。モナドを使うと、副作用を閉じ込めた環境の中で発生させ、ほかのほとんどの関数の純粋な状態に影響を与えずに済みます。

引数の読み込み

Leanでは、ファイルをスクリプトとして呼び出せます。lean --runで単体のスクリプトとして直接実行する方法と、lakeを使う方法があります。

Leanのプロジェクトにはエントリーポイントが1つだけあり、mainという関数です。この関数は、渡されたすべての引数を含むList Stringを受け取ります。 この演習では、Grep.leanを実行ファイルとして実行する状況を再現するために、同じ方法で引数が渡されます。

ファイルの読み込み

Leanには、IO.FSモナドでファイルを操作するための関数が用意されています。 たとえば、IO.FS.readFileを使うと、指定したパスにあるファイルの内容をStringとして読み込めます。

出力の書き込み

この演習では、値を返す代わりに、結果を標準出力または標準エラーに書き出す必要があります。 そのための関数がLeanには用意されています。

システムエラーの処理

Exceptのエラーとは異なり、IOの例外は実際には実行時の例外です。 これらを処理するには、try/catchを使います。

try
    /- 
        code that may possibly raise an exception 
    -/
catch msg =>
    /-
        code that is executed only if an exception was thrown
    -/
GitHubで編集する リンクは新しいウィンドウまたはタブで開きます
Lean Exercism

Grepを始める準備はできましたか?

Exercismに登録すれば、100個の演習、そして本物の人間によるメンタリングとともに、Leanを学んでマスターできます。すべて無料です。