【Linux】grepコマンドの使い方|文字列検索・正規表現・再帰検索・オプション

grepは、ファイルの中から特定の文字列(パターン)を含む行を検索するLinuxの定番コマンドです。ログからERRORの行だけを抜き出したり、設定ファイルから特定のキーワードを探したり、ほかのコマンドの出力を絞り込んだりと、Linuxを使ううえで欠かせません。名前は「global regular expression print」に由来し、正規表現での検索もできます。

つまずきやすいのは、検索パターンが正規表現として扱われること(.*が特別な意味を持つ)と、サブフォルダまで検索するには-rが必要なことです。この記事では、実機のLinux(WSLのDebian)で実際にコマンドを動かしながら、grepの使い方を整理します。

先に結論

  • 基本はgrep "検索文字列" ファイル名。一致する行が表示されます。
  • -iで大文字小文字を無視、-nで行番号、-vで一致しない行、-cで件数。
  • サブフォルダも検索するには-r(再帰)を付けます。
  • パターンは正規表現。記号を文字どおり探すなら-F(固定文字列)を使います。
  • -oで一致部分だけ、-wで単語単位、-Eで拡張正規表現。
  • コマンド | grep ...のように、ほかの出力を絞り込むのが定番です。

ほかの基本コマンドはよく使うLinuxコマンドまとめ、ディレクトリ移動はcdコマンド、Windowsでgrep相当のことをするならPowerShellのSelect-Stringもあわせて参考になります。

スポンサーリンク

grepの基本

もっとも基本的な使い方は、grep "検索文字列" ファイル名です。指定した文字列を含む行が、そのまま表示されます。

基本の検索
# ファイルから ERROR を含む行を探す
grep "ERROR" app.log

# 出力例:
# ERROR disk full

# 複数ファイルをまとめて検索(ファイル名も表示される)
grep "ERROR" *.log

実機でも、grep "ERROR" a.logERROR disk fullの行を表示しました。検索文字列はクォート("...")で囲むのが安全です(スペースや記号を含む場合に特に重要)。複数のファイルを*.logのように指定すると、まとめて検索でき、どのファイルの行かも表示されます。

よく使うオプション(-i / -n / -v / -c)

grepには便利なオプションが多数あります。まず覚えたいのが、大文字小文字を無視する-i、行番号を表示する-n、一致しない行を表示する-v、件数を数える-cです。

よく使うオプション
# -i: 大文字小文字を無視(error でも ERROR がヒット)
grep -i "error" app.log

# -n: 行番号を表示
grep -n "ERROR" app.log     # 2:ERROR disk full

# -v: 一致「しない」行を表示(ノイズ除去に便利)
grep -v "DEBUG" app.log

# -c: 一致した行数を数える
grep -c "ERROR" app.log

実機でも、-ierrorERRORにヒットし、-n2:ERROR disk fullのように行番号が付き、-v "ERROR"ERROR含まない行だけが表示されました。-vは、特定のノイズ(DEBUG行など)を除いて中身を確認したいときに重宝します。-cは件数を数えるので、「エラーが何件出たか」をすぐに把握できます。

再帰検索(-r / -l)

注意したいのが、サブフォルダの中まで検索するには-r(再帰)が必要なことです。フォルダを指定して-rを付けると、その中のすべてのファイルを検索します。ファイル名だけを知りたいときは-lを使います。

再帰検索とファイル名のみ
# カレント以下すべてのファイルから ERROR を検索(grep -r 相当)
grep -r "ERROR" .

# 出力例: ファイル名:一致した行
# ./a.log:ERROR disk full
# ./sub/b.log:ERROR timeout

# -l: 一致したファイル名だけを表示
grep -rl "ERROR" .
# ./a.log
# ./sub/b.log
サブフォルダは-rで再帰検索

実機で確認したところ、grep -r "ERROR" .はカレントディレクトリのa.logだけでなく、サブフォルダのsub/b.logからも該当行を見つけ、./a.log:ERROR disk fullのようにファイル名付きで表示しました。-rを付けないと、ディレクトリを指定しても中身までは検索されません。「フォルダの中を全部探したのに見つからない」というときは、-rを付けているか確認してください。-l(小文字のエル)を付けると、一致した行ではなく一致したファイル名だけが表示されるので、「どのファイルにキーワードが含まれるか」をざっと知りたいときに便利です。特定の拡張子だけを対象にしたいときは、grep -r "ERROR" --include="*.log" .のように--includeで絞り込めます。

パターンは正規表現(-Fで固定文字列)

重要な注意点です。grepの検索パターンは正規表現として解釈されます。たとえば.(ドット)は「任意の1文字」を意味するため、a.bで検索するとaXbのような文字列にもヒットします。記号を文字どおりに検索したいときは-F(固定文字列)を使います。

正規表現と固定文字列
# パターンは正規表現。. は「任意の1文字」になる
grep "a.b" file.txt
#  → "a.b" だけでなく "aXb" や "a1b" にもヒットする

# -F: 文字どおり "a.b" を探す(固定文字列・記号をそのまま扱う)
grep -F "a.b" file.txt
#  → 文字どおりの "a.b" だけにヒット

# IPアドレスやバージョン番号など記号を含む検索は -F が安全
grep -F "192.168.1.1" access.log
記号を含む検索は-Fで固定文字列に

実機で確認したところ、a.baXbの2行があるファイルに対して、通常のgrep "a.b"両方ともヒットしました(.が任意の1文字としてXに一致)。一方、grep -F "a.b"a.bの行だけにヒットしました。IPアドレス(192.168.1.1)やバージョン番号、ファイルパスなど、.*[などの記号を含む文字列をそのまま検索したいときは、-Fを使うと意図しないヒットを防げます(fgrepという別名コマンドも同じ働きです)。逆に、正規表現のパターンマッチを活かしたいときは-Fを付けずに使います。

-o / -w / -E(一致部分・単語・拡張正規表現)

さらに便利なオプションです。-oは一致した部分だけを表示、-wは単語単位で一致、-Eは拡張正規表現(+?などをそのまま使える)を有効にします。

一致部分・単語・拡張正規表現
# -o: 一致した部分だけを抜き出す(数字だけ取り出す、など)
echo "price 3.14 yen" | grep -o "[0-9.]*"     # 3.14

# -w: 単語単位で一致(cat は一致、category は不一致)
grep -w "cat" file.txt

# -E: 拡張正規表現(+ ? | () などをそのまま使える)
grep -E "foo[0-9]+" file.txt     # foo1, foo22 などにヒット
grep -E "error|warning" app.log  # error または warning

実機でも、-o "[0-9.]*"price 3.14 yenから3.14だけを抜き出せ、-w "cat"catに一致しcategoryには一致しませんでした。-Eを使うとfoo[0-9]+fooの後に数字が1個以上)やerror|warning(どちらか)といった拡張正規表現がそのまま書けます-Eを付けないと+|はそのままの文字として扱われるため、複雑なパターンでは-Eを付けるのが便利です(egrepという別名でも同じです)。

パイプと組み合わせる

grepがもっとも活躍するのが、ほかのコマンドの出力を絞り込む使い方です。|(パイプ)でコマンドの出力をgrepに渡します。

パイプで出力を絞り込む
# 実行中のプロセスから特定のものを探す
ps aux | grep nginx

# ファイル一覧から特定の拡張子を探す
ls -l | grep ".log"

# コマンド履歴から git を含むものを探す
history | grep git

# 複数の grep をつなげて絞り込む(AND検索のように)
grep "ERROR" app.log | grep "disk" 

ps aux | grep nginxのように、コマンドの出力を|grepに渡すと、必要な行だけに絞り込めます。Linuxでは「コマンドの出力をgrepで絞る」のが非常によく使われるパターンです。grep ... | grep ...とつなげれば、両方の条件を満たす行(AND検索のような絞り込み)もできます。ログ調査やプロセス確認で、日常的に使うテクニックです。

主なオプション一覧

grepでよく使うオプションをまとめます。

オプション 働き
-i 大文字小文字を無視する
-n 行番号を表示する
-v 一致しない行を表示する
-c 一致した行数を数える
-r サブフォルダも再帰的に検索
-l 一致したファイル名だけ表示
-o 一致した部分だけ表示
-w 単語単位で一致
-E / -F 拡張正規表現 / 固定文字列

よくある失敗

サブフォルダが検索されない

-rを付けないと再帰検索されません。grep -r "語" .とします。

記号を含む検索でヒットしすぎる

パターンは正規表現です。記号を文字どおり探すなら-Fを使います。

検索文字列をクォートで囲まない

スペースや記号を含むとうまく動きません。"..."で囲みます。

大文字小文字で見つからない

区別したくないときは-iを付けます。

+ や | がそのままの文字として扱われる

拡張正規表現には-Eが必要です。付けないと記号がそのままの意味になります。

よくある質問

Qgrepでファイルの中身を検索するには?
Agrep "検索文字列" ファイル名で、その文字列を含む行が表示されます。複数ファイルはgrep "語" *.log、サブフォルダも含めるならgrep -r "語" .とします。大文字小文字を無視するなら-iを付けます。
Qサブフォルダの中まで検索するには?
A-r(再帰)オプションを付けます。grep -r "検索語" ディレクトリで、その中のすべてのファイルを検索します。一致したファイル名だけを知りたいときは-l、特定の拡張子だけなら--include="*.log"を併用します。
Q検索したい文字に . や * が含まれます。
Agrepのパターンは正規表現なので、.*は特別な意味を持ちます。文字どおりに検索したいときは-F(固定文字列)を付けてください。IPアドレスやバージョン番号など、記号を含む文字列の検索では-Fが安全です。
Q一致しない行だけを表示するには?
A-vオプションを使います。grep -v "DEBUG" app.logで、DEBUGを含まない行だけが表示されます。特定のノイズ行を除いて中身を確認したいときに便利です。
Qコマンドの出力を絞り込むには?
A|(パイプ)でgrepに渡します。ps aux | grep nginxのように書くと、コマンドの出力から必要な行だけを抜き出せます。grep ... | grep ...とつなげれば、複数条件での絞り込みもできます。

まとめ

  • 基本はgrep "検索文字列" ファイル名。一致する行を表示します。
  • -i(大小無視)・-n(行番号)・-v(否定)・-c(件数)が定番です。
  • サブフォルダは-rで再帰検索します。
  • パターンは正規表現。記号を文字どおり探すなら-Fを使います。
  • コマンド | grep ...で、出力の絞り込みに大活躍します。

grepは、Linuxでもっともよく使うコマンドの1つです。「-rで再帰」「記号は-Fで固定文字列」の2点を押さえ、パイプと組み合わせれば、ログ調査やファイル検索を効率よくこなせます。まずは基本の検索から始めて、少しずつオプションを使いこなしていきましょう。