ファイル内の特定の文字列を検索するには、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 を通してパイプする必要があります。パイプの記号は | です。
次の例では、ファイル名が .ps で終わるファイルのうち、9 月 (September) に作成されたファイル名とその詳細情報を表示させます。
$ ls -l *.ps | grep Sep |
上記のコマンドの最初の部分は、.ps で終わるファイルの一覧を出力します。
$ ls -l *.ps -rw-r--r-- 1 user2 users 833233 Jun 29 16:22 buttons.ps -rw-r--r-- 1 user2 users 39245 Sep 27 09:38 changes.ps -rw-r--r-- 1 user2 users 608368 Mar 2 2000 clock.ps -rw-r--r-- 1 user2 users 827114 Sep 13 16:49 commands.ps $ |
コマンド行の次の部分は、grep を使用してパイプ処理を行い、Sep というパターンを検索します。
| grep Sep |
この検索の結果、次のように表示されます。
$ ls -l *.ps | grep Sep -rw-r--r-- 1 user2 users 39245 Sep 27 09:38 changes.ps -rw-r--r-- 1 user2 users 827114 Sep 13 16:49 commands.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 コマンドで正規表現を使用する場合は、これらのメタキャラクタをエスケープしてこれらの文字の特殊な意味を無視するようにシステムに伝える必要があります。コマンドプロンプトで grep の正規表現を使用する場合は、引用符で囲んでください。メタキャラクタ (& ! . * $ ? \ など) は、バックスラッシュ (\) でエスケープしてください。メタキャラクタのエスケープについての詳細は、メタキャラクタの検索 を参照してください。
キャレット (^) メタキャラクタは、行の先頭を表します。たとえば、次のコマンドはファイル list 内の b という文字で始まる行を見つけ出します。
$ grep '^b' list |
ドル記号 ($) は、行の終わりを示します。たとえば、次のコマンドは b で終わる行を表示します。
$ grep 'b$' list |
また、次のコマンドは、ファイル list 内の行のうち b という文字しか含まれない行を表示します。
$ grep '^b$' list |
正規表現内のドット (.) は任意の 1 文字を表します。したがって、次のコマンドは最初の 2 文字が an である任意の 3 文字を含む文字列を検索します。検索される文字列には、たとえば 「any」、「and」、「management」、「plan」 (空白も 1 文字と数えられるため) などがあります。
$ grep 'an.' list |
ある文字のすぐ後にアスタリスク (*) が続いている場合、grep は * を「その直前の文字のゼロ個以上の繰り返し」と解釈します。正規表現の後にアスタリスクが続いている場合、grep は * を「正規表現のパターンに一致する文字のゼロ個以上の繰り返し」と解釈します。
「ゼロ個以上の繰り返し」という表現のため、その使い方が直観的には理解しにくいかも知れません。たとえば、qu という文字列を含むワードをすべて検索するには次のように入力します。
$ grep 'qu*' list |
しかし、n という文字を含むワードをすべて検索するには、次のように入力します。
$ grep 'nn*' list |
また、nn というパターンを含むワードをすべて検索するには、次のように入力します。
$ grep 'nnn*' list |
ファイル list 内で任意の文字のゼロ個以上の繰り返しを検索するには、次のように入力します。
$ grep .* list |
grep コマンドを使用してメタキャラクタ (& ! . * ? \ など) を検索するには、メタキャラクタの前にバックスラッシュ (\) を付けます。バックスラッシュを付けることで、grep はそのメタキャラクタをエスケープし、通常の文字として扱います。
たとえば、次の正規表現は、ピリオド (.) で始まる行を検索するため、nroff または troff の書式要求 (ピリオドで始まるもの) を検索するときに非常に便利です。
$ grep '^\.' |
表 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(1) コマンドについての詳細は、『man pages section 1: User Commands』を参照してください。