grepによるパターンの検索

目次 grep コマンドの 基本形式は, grep string fileです。 fileで 指定した ファイルの 中から string に 一致する 文字列を 含む 行を 探して 表示します。

grepをフィルタにする

grep コマンドは フィルタとして 使用できます。 この場合 file を 指定せず、 標準入力の 中から 探します。

例えば、 last という コマンドは、 そのシステムの過去のログイン情報を 表示します。 この中から 自分に 関する 情報を 取り出すには。

sw99% last | grep 99ss999
99ss999 console      Sun Dec  5 11:11   ログイン中です   
....
とすれば いいわけです。

指定文字列を 含まない 行の 検索を するには、-v オプションを 使います。 shutdown を除いた過去のログイン情報を表示してみましょう。

sw99% last | grep -v shutdown
....

grepの詳細

特殊な文字

grep コマンドに とっての 特殊文字の 中には、 Cシェルに とっても 特殊な 意味を 持つ 文字が あります。 このため、 バックスラッシュ (¥) で エスケープするか、 シングルクォート (’) で 囲んでやる 必要が あります。

行の頭

サーカムフレックス(^)は 行頭を 表します。 Cシェルの例題で作成した friends という ファイルを使って練習しましょう。
sw99% cd ~/core-info
sw99% ls
friends hello
sw99% cat friends
Tsutomu
Atsushi
Mariko
...
sw99% grep '^A' friends
Atsushi
...

行の終わり

また、 ドル記号 ($) は 行の 終わりを 表します。
sw99% grep 'ko$' friends
Mariko
...

任意の文字との一致

ピリオド (.) は 任意の 1文字と 一致します。 (Cシェル コマンド ライン での ? に 相当します。) 例えば、 ^...t と すると、 先頭から 4文字めが t で あると いうことに なります。
sw99% grep '^...t' friends
Tsutomu
...

繰り返し

アスタリスク(*)が 文字または パターンの 後ろに ついたときは、 「その文字 または パターンが 0 回以上 任意回数 繰り返される」と 解釈します。 0 回も 許される ので、 注意が 必要です。

/usr/dict/words には英語のスペルチェック用の辞書があります。これを使って パターンマッチングの練習をしてみましょう。 例えば "n" が 1文字以上 続いた 後に m が 来る 単語を 検索する には、 次の ように します。

sw99% grep 'nn*m' /usr/dict/words 
cornmeal
cottonmouth
....
また、 "o" が 2文字 以上 続いた 後に p が 来る 単語を 検索するには、 grep 'ooo*p' /usr/dict/words の ように します。

ドル記号や アスタリスクなどの 特殊文字を 含む 行を 検索するには、 バックスラッシュ(\,¥)を 付けて エスケープします。

[] ... いくつかの文字のうち どれか一つ

大括弧 [ ] で かこむと その中の 1文字と 一致する 文字を 検索します。
sw99% grep '^[ab][ab][ab]' /usr/dict/words 
aback
...
babysitting
サーカムフレックス(^)が 大括弧の 中に あると、 その後の 文字と 一致しない という意味になります。
sw99% grep '^[^a-z]q' /usr/dict/words 
Aquarius
...

スペースを 含む 文字列を 検索する 時には、 検索文字列全体を ダブルクォート(") で 囲みます。

grep の検索パターン要素をまとめると次のようになります。

^行頭
$行末
.任意の1文字
[...]大括弧の 中の 任意の 1文字と 一致する 1文字
[^...]大括弧の 中の 任意の 1文字と 一致しない 1文字
*直前の 文字または 正規表現 (パターン) の 0回 以上の 繰り返し
.*0文字 以上の 任意の 文字列
¥(\)エスケープ (次の 文字の 特別な 意味を なくす)

練習問題

  1. last から shutdown だけでなく reboot も取り除いて表示しなさい。
  2. /usr/dict/words の中から数字の入った単語を取り出しなさい。
  3. /usr/dict/words の中から a で始まって b で終わる単語を取り出しなさい。
  4. 自分宛のメールは /var/mail/99ss999 (自分のIDに変える) に入っています。 このファイルをメールスプールと呼びます。 また、1通のメールは 'From ' (Fromと空白) で始まる行から始まります。 これを、ここではメールセパレータと呼ぶことにします。
    メールスプールから、メールセパレータを取り出し表示しなさい。 (メールツールの表示と比較してください)
  5. メールセパレータに表示されるメールアドレスは「本当の」送信人です。 これは、時には自動転送するプログラムが付ける名前であったりします。 「名義上」の送信人は 'From: ' で始まる行に書いてあります。
    メールスプールから、名義上の送信人の行を取り出して表示しなさい。 (メールツールの表示と比較してください)

宿題

次回の授業で awk によるデータ処理を勉強します。この時に使うデータとして、 1週間の「こづかい帳」をつけて来てください。「こづかい帳」の形式は以下の ようにしてください。
日付 事項 分類 金額
1206 start in 30000
1206 lunch eat 400
1206 socks other 500
1206 dinnereat 500
1207 bank in 5000
...
...
日付は4桁の数字、事項は簡単な英語(ローマ字)、 分類は in(収入) eat(食費) other(その他) 金額は円。各コラムは1つ以上のスペース又はタブで 区切る。また、事項の中にスペースが入ると混同するので スペースは入れないこと。(必要な場合は - または _ で代用)

「こづかい帳」は各自のパソコンに作成して、 メールや FTP を使ってワークステーションへ転送してください。 (どうしてもできなければ、紙にメモしてワークステーションで 作成してもかまいません)

データの正確さは問いません。プライバシーに関するデータは 必要ありません。(デート費用とか、、、)


パソコンで awk の勉強をしたい人は、 GNU awk をインストールしてください。インストール方法は ファイルとディレクトリの付録を参照のこと。