地元の図書館で、古い本のコレクションの整理を手伝う仕事に就きました。学生の利用者は、学期末レポートに引用したい、うろ覚えの一節を探していることがよくあります。1冊ずつ最初から最後まで手作業で読む代わりに、それらの本をスキャンして、そうしたうろ覚えの一節を探す小さなツールを作ることにしました。
ファイルから検索文字列に一致する行を探し、一致したすべての行を返します。
Unixのgrepコマンドは、正規表現に一致する行をファイルから探します。
ここでの課題は、固定文字列の検索に対応した簡略版のgrepコマンドを実装することです。
grepコマンドは3つの引数を取ります。
次に、指定されたファイルの内容を(指定された順に)読み込み、検索文字列を含む行を探し、最後に見つかった順にそれらの行を返します。
複数のファイルを検索する場合、一致した各行の先頭にはファイル名とコロン(:)が付きます。
grepコマンドは次のフラグに対応しています。
-n 出力の各行の先頭に行番号とコロン(:)を付けます。行番号はファイル名の後ろに置きます(ファイル名がある場合)。-l 一致する行を1つ以上含むファイルの名前だけを出力します。-i 大文字と小文字を区別せずに比較して照合します。-v プログラムの動作を反転させ、一致しなかったすべての行を集めます。-x 検索文字列が行全体と一致する行だけを探します。Powershellは関数のスイッチパラメーターに対応しており、これはコマンドラインのフラグと同じような働きをします。
Powershellでは、コマンドレットやそのプロパティに詳しく説明的な名前を付けるのが慣習です。それに合わせて、この演習で使うフラグも名前が変わり、言語を反映したものになっています。
Line(-n):出力の各行の先頭に行番号とコロン(':')を付けます。番号はファイル名(あれば)の後に置きます。File(-l):少なくとも1行一致する行を含むファイルの名前だけを出力します。Insensitive(-i):大文字と小文字を区別しない比較で照合します。Invert(-v):プログラムの動作を反転させます。一致しなかった行をすべて集めます。Whole(-x):検索文字列が行全体と一致する行だけを探します。主な目的はgrep関数の実装です。ファイルへのパスを正しく取得することは気にしなくてかまいません。
この演習では、テストスイートで3つの必須テキストファイル、iliad.txt、midsummer-night.txt、paradise-lost.txtが用意されます。通常のファイルパスの代わりに、名前の文字列を使ってGet-Contentでその内容にアクセスするだけでかまいません。
Powershellには、grepに似たSelect-Stringというコマンドレットがあります。興味があれば、こちらで詳しく読むことができます。
この演習では、いかなる場面でもSelect-Stringを使わないでください。