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


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

コマンド grep ファイルから指定のパターンにマッチする行を検索する

最終更新


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

目次:
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 マッチした行のオフセット (開始バイト数) を表示
% grep -b foo sample.txt
0:foo
18:aafoobb
⇒ foo の行は sample.txt の 0バイト目から始まり、aafoobb の行は sample.txt の 18バイト目から始まることがわかる
-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=[パターン]
明示的に検索パターンを指定する。パターンは正規表現として扱われる。

パターンが 1つだけの場合、以下の 2つは同じである (-e オプションを付けても付けなくてもよい)
% grep hoge sample.txt
% grep -e hoge sample.txt

-e オプションは複数個のパターンを指定するときによく使用される。
例えば「rwx」または「r-x」を含む行を検索しようとして、
% ls -l | grep 'rwx' 'r-x'
とすると、grep は 「r-x」というファイルを見付けようとしてエラーになってしまう。こういう場合は -e オプションを複数個指定し、
% 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 中の文字列を検索パターンとして使う。
-h または --no-filename
出力行の先頭のファイル名を表示しない。grep コマンドのデフォルトでは
% grep hoge *.txt
sample1.txt: hogehoge
sample1.txt: aahoge
sample2.txt: hogefuga
のように、各行の先頭にファイル名を表示するが、-h オプションを使うと
% grep hoge *.txt
hogehoge
aahoge
hogefuga
というふうにファイル名表示を抑止する。
-i または --ignore-case
大文字小文字を区別しない。
-l 指定文字列を含むファイル名を表示。
指定の文字列を含むファイルが何個あるか数えるには
% grep -l hoge *.txt | wc -l
とする。
-L または --files-without-match
指定文字列を含まないファイル名を表示。
-n または --line-number
マッチした行の行番号を表示する。
% grep -n hoge *.txt
sample1.txt:26: hogehoge
sample1.txt:128: aahoge
sample2.txt:3 hogefuga
-P または --perl-regexp
Perl 互換の正規表現 (PCRE) を使う。
-r ディレクトリを再帰的にたどって、ファイルを検索する。
通常の場合は "grep PATTERN [対象ファイル]" であるが、-r オプションを指定した場合は "grep -r PATTERM [対象ディレクトリ]" とする。
% grep -r hoge .
→ カレントディレクトリ以下のファイルから再帰的に hoge を検索する
% grep -r hoge dir/ dir2/
→ ディレクトリ dir と dir2 以下のファイルから再帰的に hoge を検索する
-r オプションで再帰的に検索する場合は、--include オプション・--exclude オプション・--exclude-dir オプションで絞り込むのが便利である。こちら を参照してほしい。
-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
--line-buffered 出力バッファリングにおいて、行バッファリングとする。
例えば
% tail -f /var/log/syslog | grep hoge | grep -v fuga
のように tail の後に grep コマンドを 2段に重ねた場合、最初の grepコマンド が出力時にバッファリングを行なってしまうためログに追記された内容がすぐには表示されない。そのようなときは以下のように --line-buffered オプションを使うとよい (Linux と *BSD で使用可。FreeBSD は 5.3-RELEASE 以降)。
% tail -f /var/log/syslog | grep --line-buffered hoge | grep -v fuga

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

Howto: 検索結果にファイル名のみを表示する
-l オプションを使うことで、該当文字列が存在するファイル名のみを表示できる。
% grep hoge *.txt
sample.txt
sample2.txt

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

Howto: 複数条件 (AND 条件) での検索
grep をパイプで複数段つなげることで、AND 条件を指定できる。
% grep aaa *.txt | grep bbb | grep ccc
ただしこの場合は、「同一行に aaa と bbb と ccc が出現する行を検索する」という意味であることに注意。もし、「同一行でなくてもいいので、aaa と bbb と ccc が出現するファイル名を表示する」が目的であれば、-l オプションと xargs を使って、下記のようにすればよい。
% grep -l aaa *.txt | xargs grep -l bbb | xargs grep -l ccc

Howto: ディレクトリを再帰的に検索する
grep に -r オプションを付けることで再帰的にディレクトリをたどって検索することができる。
% grep -r hoge .
→ カレントディレクトリ以下のファイルから再帰的に hoge を検索する
% grep -r hoge dir/ dir2/
→ ディレクトリ dir と dir2 以下のファイルから再帰的に hoge を検索する
-r オプションで再帰的に検索する場合は、--include オプションと --exclude で絞り込むのが便利である。
% grep -r --include='*.log' hoge .
→ 対象ファイルを *.log に絞る
% grep -r --exclude='*.log' hoge .
→ *.log 以外のファイルを対象に検索する
--include オプションと --exclude オプションはファイルに対してしか効果がない。ディレクトリを除外したい場合は --exclude-dir オプションを使う。
% grep -r --exclude-dir='.svn' --exclude-dir='.git' .
→ .*.log 以外のファイルを対象に検索する
残念ながら --exclude-dir オプションは FreeBSD 11.0-RELEASE ではまだ使えないようだ。

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
でもよいのだけれど。
>> Linuxオンラインマニュアル(man) Linux grep(1)
>> FreeBSDオンラインマニュアル(man) FreeBSD grep(1)
>> Solaris10オンラインマニュアル(man) Solaris10 grep(1)

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

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


頑張って書いたおすすめコンテンツ!
クラウドサービス徹底比較・徹底解説