この章では、SunOS の grep コマンドを使って、ディレクトリとファイルの内容を検索し、キーワードや文字列を見つける方法について説明します。
ファイル内の特定の文字列を検索するには、grep コマンドを使います。grep コマンドの基本構文は次のとおりです。
$ grep string file |
string は検索するワードや句、file は検索されるファイルです。
文字列とは 1 文字以上の文字の配列です。ワードや文と同様に、文字が 1 つでも文字列とします。文字列には、空白文字、句読文字、制御文字 (表示できない文字) も入ります。
たとえば、Edgar Allan Poe の内線番号を検索する場合は、grep の後に名前の一部または全体 (以下の例では Poe)、その後に内線番号の情報を含んでいるファイル名 (以下の例では extensions) を指定します。
$ grep Poe extensions Edgar Allan Poe x72836 $ |
ただし、指定されたパターンに一致するのは 1 行だけとは限らないので、注意してください。
$ grep Allan extensions David Allan x76438 Edgar Allan Poe x72836 $ grep Al extensions Louisa May Alcott x74236 David Allan x76438 Edgar Allan Poe x72836 $ |
grep では大文字と小文字が区別されます。したがって、大文字と小文字の区別に注意してパターンを指定しなければなりません。
$ grep allan extensions $ grep Allan extensions David Allan x76438 Edgar Allan Poe x72836 $ |
上記の最初の例では、小文字の a で始まるエントリがないために検索は失敗に終わっています。
grep は、「フィルタ」として他のコマンドと併用されることがよくあります。grep をフィルタとして使うと、他のコマンドの出力結果から不要な情報を除去できます。grep をフィルタとして使うには、他のコマンドの出力結果を grep を通じてパイプする必要があります。パイプの記号は | です。
次の例では、ファイル名が .ps で終わるファイルのうち、5 月 (May) に作成されたファイル名とその詳細情報を表示させます。
$ ls -l *.ps | grep May |
上記のコマンド行の最初の要素は、次の部分です。
ls -l *.ps |
このコマンドだけを実行すると、次のファイルの一覧が出力されます。
2 番目の要素は、次の部分です。
| grep May |
この部分は、上記のファイルの一覧を grep を通じてパイプし、May というパターンを検索して表示します。
$ ls -l *.ps | grep May -rw-r--r-- 1 elvis 2356 May 22 12:56 clock.ps -rw-r--r-- 1 elvis 5644 May 22 15:07 buttons.ps $ |
複数のワードからなるパターンを grep で検索する場合は、単一引用符または二重引用符でそのパターンを囲みます。
$ grep "Louisa May" extensions Louisa May Alcott x74236 $ |
grep は複数のファイル内で文字列を検索できます。複数のファイル内でパターンに一致する文字列が見つかった場合は、ファイル名とパターンに一致する行をコロンで区切って出力します。
$ grep ar * actors:Humphrey Bogart alaska:Alaska is the largest state in the United States. wilde:book. Books are well written or badly written. $ |
特定の文字列を含まない行をファイル内で検索するには、grep の -v オプションを使います。次の例は、あるディレクトリのすべてのファイル内で、文字 e を含まない行すべてを検索する方法を示しています。
$ ls actors alaska hinterland tutors wilde $ grep -v e * actors:Mon Mar 14 10:00 PST 1936 wilde:That is all. $ |
grep コマンドは、正規表現を使ったパターンの検索にも利用できます。正規表現は、grep に対して特別な意味を持つ特殊文字に、数字や英字を組み合わせて作成します。メタキャラクタと呼ばれるこれらの特殊文字はシステムに対しても特別な意味を持つため、引用符で囲むかエスケープする必要があります。コマンドプロンプトに対して grep の正規表現を使う場合は、必ず引用符で囲むか、メタキャラクタ (& ! . * $ ? ¥ など) をバックスラッシュ (¥) でエスケープします。
キャレット (^) は行の先頭を表します。したがって、次のコマンドは、ファイル list 内の b で始まる行を検索します。
$ grep '^b' list |
ドル記号 ($) は行の終わりを表します。次のコマンドは、b で終わる行をすべて表示します。
$ grep 'b$' list |
また、次のコマンドは、ファイル list 内で b だけ (b が 1 文字だけで、その前後にタブや空白さえ存在しない) からなる行を検索します。
$ grep '^b$' list |
正規表現内のドット (.) は任意の 1 文字を表します。したがって、次のコマンドは、最初の 2 文字が an の任意の 3 文字パターンを含む行を検索します。
$ grep 'an.' list |
この 3 文字パターンには、「any」、「and」、「management」、「plan 」(空白やタブも 1 文字と数えられるため、この plan は n の後に空白があります) などが一致します。
ある文字のすぐ後にアスタリスク (*) が続いている場合、grep は * を「その直前の文字のゼロ個以上の繰り返し」と解釈します。正規表現の後にアスタリスクが続いている場合、grep は * を「正規表現のパターンに一致する文字のゼロ個以上の繰り返し」と解釈します。
「ゼロ個の繰り返し」という表現のため、その使い方が直観的には理解しにくいかも知れません。たとえば、qu という文字列を含むワードをすべて検索する場合は、次のように入力すれば期待通りの結果が得られます。
$ grep 'qu*' list |
しかし、文字 n を含むワードをすべて検索する場合は、次のように入力しなければなりません。
$ grep 'nn*' list |
また、nn というパターンを含むワードをすべて検索する場合は、次のように入力しなければなりません。
$ grep 'nnn*' list |
このように指定しなかった場合の結果を確認する場合は、次の例を試してください。
ファイル list 内で任意の文字のゼロ個以上の繰り返しを検索するには、次のように入力します。
$ grep '.*' list |
テキストファイル内でドル記号 ($) を含む行を検索すると想定します。正規表現内のドル記号の前にバックスラッシュ (¥) を付けると、$ が持つ特殊な意味を無視 (エスケープ) するよう grep に指示できます。その他のメタキャラクタ (& ! . * ? および ¥ 自身など) についてもこの方法を適用できます。
たとえば、次の正規表現は、ピリオド (.) で始まる行と一致するため、nroff や troff の書式要求 (ピリオドで始まるもの) を検索するときに非常に便利です。
$ grep '^¥.' filename |
次の表 4-1 は、grep で利用できる検索パターン文字のうち、頻繁に使われる文字のリストです。
表 4-1 grep の検索パターン文字
文字 |
意味 |
---|---|
^ |
テキスト行の先頭 |
$ |
テキスト行の終わり |
. |
任意の 1 文字 |
[...] |
角括弧内のリストまたは範囲に含まれる任意の 1 文字 |
[^...] |
角括弧内のリストまたは範囲に含まれない任意の 1 文字 |
* |
その直前の文字または正規表現のゼロ個以上の繰り返し |
.* |
任意の 1 文字のゼロ個以上の繰り返し |
¥ |
その後の文字が持つ特殊な意味を無効にする |
これらの検索パターン文字は、vi テキストエディタ内での検索にも使えます。
すでに述べたように、grep に 1 つの単位として解釈させるテキストは引用符 (") で囲みます。たとえば、grep を使って「dang it, boys」という句を含むすべてのファイルを検索するには、次のように入力します。
$ grep "dang it, boys" * |
複数のワードからなる句を 1 つの単位にまとめる場合は、単一引用符 (') も使えます。単一引用符を使うと、$ などの特殊文字を単なる文字として解釈させることもできます。(history コマンドのメタキャラクタ ! は、バックスラッシュでエスケープしないと、引用符の中にあっても常に特殊文字として解釈されます。) どのような場合でも、& ! $ ? . ; ¥ などの特殊文字を通常の印字文字として解釈させるときは、それらをバックスラッシュでエスケープすることをお勧めします。
たとえば、次のように入力すると、list 内のすべての行が表示されます。
$ grep $ list |
しかし、次のように入力すれば、文字 $ を含む行だけが表示されます。
$ grep '¥$' list |
grep コマンドについての詳細は、『SunOS リファレンスマニュアル (1): ユーザーコマンド』を参照してください。