UNIX/Linuxの部屋 コマンド: grep


※空白区切りで AND 検索 (例:「ファイル 削除」)

コマンド grep 指定のパターンにマッチする行を表示(パイプ)

UNIX/Linux の grep コマンドは、ファイルの中から指定の文字列を検索するコマンドである。複数ファイルからの検索や、複数条件での検索、正規表現のパターン指定、特定パターン除外指定、ディレクトリをたどる再帰的検索などを行うことができる。

基本的な使い方
あるファイルの中に、指定の文字列を含む行を表示する。例えば、sample.dat の中の「hoge」という文字列を含む行を表示したい場合、
% grep hoge sample.dat
とする。また、
% grep hoge file1 file2 file3
% grep hoge dir/*
などとすると、複数のファイルについて調べることができる。

検索したい文字列には正規表現を使うことができる。例えば
% grep '[a-z]' sample.dat
とすると、a〜z を含む行を全て表示する。ただし、grep コマンドはデフォルトでは限定正規表現しか扱えないことに注意 (-E オプションを参照)。

FreeBSD や Linux は他 grep に比べて高機能である grep (GNU grep) コマンドを標準採用しているが、Solaris などはデフォルトの grep は (GNU grep と比べると) 低機能で、-e オプションや -E オプションを使うことができない。Solaris の場合、/usr/xpg4/bin/grep が多少は高機能な grep となっているが、GNU grep ほどではない。

grep コマンドの用途はとても広い。
  • /var/log/ にあるログファイルから、特定のメッセージを抜き出す
  • /var/log/ にあるログファイルから、特定の日付のみのログを抜き出す
  • /usr/include/ から、特定のマクロがどこで定義されているか調べる
などなど。grep コマンドを使いこなせていないとしたら、その人の UNIX のスキルは知れたものである。ぜひ有効な使い方を覚えてほしい。

grep コマンドのオプション
-num マッチした文字列の前後 num 行を表示する。
デフォルトは -0。つまりマッチした行のみを表示するということ。
-A [num] または --after-context=[num]
マッチした文字列の後に続く num 行を表示する。
-B [num] または --before-context=[num]
マッチした文字列の前の num 行を表示する。
-a または --text
バイナリファイルであったとしても、テキストファイルのように扱う。grep コマンドはバイナリファイルに対してはマッチした行を表示するのではなく、一致したことだけを伝える。
% grep a /bin/ls
バイナリファイル /bin/ls に一致しました
→ または Binary file /bin/ls matches
しかしながら、テキストファイル内に一部不正データが混入している場合など、本当はテキストファイルとして扱ってほしい場合は、-a または --text オプションを使うことで、テキストファイルのように取り扱うことができる。バイナリファイル内の文字列を検索したい場合は string コマンドの使用を検討すること。
-b マッチした文字列のオフセットを表示
-C -2と同じ
-c または --count
テキスト中に文字列が含む行の行数を表示する。-v と組み合わせると、含まない行数を表示する。
% grep -c hoge a.txt
5
→ a.txt には hoge を含む行が 5行ある
% grep -c -v hoge a.txt
8
→ hoge を含まない行は 8行ある
複数ファイルに対しても実行すると、ファイル名と行数を表示する。
% grep -c hoge *
a.txt:5
b.txt:9
c.txt:0
% grep -c hoge * | sort -t: -k2n
→ 行数の昇順でソート
-e [パターン] または --regexp=[パターン]
明示的に検索パターンを指定する。正規表現となる。複数個のパターンを指定するときに使う
「rwx」と「r-x」を含む行を検索しようとして、
% ls -l | grep 'rwx' 'r-x'
とすると、grep は 「r-x」というファイルを見付けようとしてエラーになってしまう。こういう場合は
% ls -l | grep -e 'rwx' -e 'r-x'
とすればよい。低機能版の grep には -e オプションは効かないので注意。
-E [パターン] または --extended-regexp=[パターン]
拡張正規表現を使う。デフォルトでは 「?+|{}()」などは普通の文字として扱われてしまうので、「foo」と「bar」を含む行を表示しようとして、
% grep 'foo|bar' sample.txt
としても、'foo|bar' という普通の文字列だと認識されてしまう。
% grep -E 'foo|bar' sample.txt
だと拡張正規表現として扱われるので、うまくいく。低機能版の grep には -E オプションは効かないので注意。grep -E は egrep とほぼ同じである。
-F 固定文字列として検索する。
. * ? などのメタキャラクタを指定しても、正規表現としての意味を持たなくなる。grep -F は、fgrep と同じである。
-f [file] または --file=[file]
ファイル file 中の文字列を検索パターンとして使う。
-i または --ignore-case
大文字小文字を区別しない。
-l 指定文字列を含むファイル名を表示。
指定の文字列を含むファイルが何個あるか数えるには
% grep -l hoge *.txt | wc -l
とする。
-L または --files-without-match
指定文字列を含まないファイル名を表示。
-n または --line-number
マッチした行の行番号を表示する。
-P または --perl-regexp
Perl 互換の正規表現 (PCRE) を使う。
-R ディレクトリを再帰的にたどって、ファイルを検索する。
FreeBSD の grep では使えるが、他の UNIX では -R オプションは使えない場合が多い。
-s または --no-messages
エラーメッセージを抑制する(ファイルに対しての permission denied など)。
-w または --word-regexp
ファイル中の指定文字列が独立している場合だけマッチしたものとみなす。
% cat test
sample // 独立した文字列ではないのでマッチしない
samp // 記号や空白でかこまれた文字列はマッチする
samp2 // 数字は記号とみなされない
,samp-
(samp&
samp/
% grep -w samp test
samp
,samp-
(samp&
samp/
-x または --line-regexp
指定文字列がそのまま1行にあるものだけマッチしたものとみなす。つまり
% grep -x abc

% grep '^abc$'
と等価。
-v または --invert-match
指定文字列を「含まない」行を表示 (正規表現にマッチしたら除外する)。
% grep -v hoge sample.txt
→ sample.txt の、hoge を含む行を除外し、それ以外を表示する。
-Z 圧縮したファイルを grep する。
% compress file.txt
% grep -Z hoge file.txt.Z

必ず覚えてほしいオプションは、-i、-e、-n、-v である。

Howto: 複数条件での検索
-e オプションを複数指定することで、複数条件を指定できる。
% grep -e aaa -e bbb -e ccc *.txt
正規表現で | でつなげてもよい。通常の grep なら \| とエスケープする。egrep なら | をそのままでよい。
% grep 'aaa\|bbb\|ccc' *.txt
% egrep 'aaa|bbb|ccc' *.txt

Howto: 大文字小文字を同一視する
-i オプション指定することで、大文字小文字を区別しないようにできる。
% grep -i aaa *.txt
→ aaa でも AAA でも aAA でもマッチする。

Howto: プロセスの検索
現在実行中のプロセスから abc という表示を抜き出すには
% ps ax | grep abc (SystemV 系 UNIX なら ps -ef)
とすればよいが、プロセス実行のタイミングによっては
% ps ax | grep abc
118 ?? Ss 0:00.03 abc
760 p3 R+ 0:00.00 grep abc
と、grep 自身がマッチしてしまうことがある。こういうときは
% ps ax | grep '[ a]bc'
とすればよい。grep '[ a]bc' を実行すると、ps の出力には
760 p3 R+ 0:00.00 grep [ a]bc
となるが、[ a]bc 自体は正規表現と解釈されるので、
760 p3 R+ 0:00.00 grep [ a]bc
の行にはマッチしないわけである。まぁ、単純に
% ps ax | grep abc | grep -v grep
でもよいのだけれど。
>> Solaris10オンラインマニュアル(man) Solaris10 grep(1)
>> FreeBSDオンラインマニュアル(man) FreeBSD grep(1)
>> Linuxオンラインマニュアル(man) Linux grep(1)

読み方 grep (UNIXコマンド) [ぐれっぷ]

ed コマンドの "g/RE/p"(Global Regular Expression Print) の略。


頑張って書いたおすすめコンテンツ!