grep はテキストから正規表現にマッチする行を抽出するコマンド。ログ解析・コード検索・設定ファイルの確認など、あらゆるテキスト検索の基本ツールだ。さらに高速な代替として Rust 製の ripgrep がある。この記事では grep の基本から正規表現パターン、実践ユースケース、ripgrep への移行まで一通りカバーする。
「ログファイルからエラーだけ抜き出したい」「コードベースから特定の関数を全部探したい」「設定ファイルからコメント行を除外して中身だけ見たい」
こういう場面で真っ先に出番が来るのが grep だ。そしてその進化版が ripgrep である。
grep とは
grep は Global Regular Expression Print の略だ。テキストから正規表現にマッチする行を抽出するフィルタコマンドで、Unix/Linux の世界では最も基本的なツールの一つである。
主な特徴:
- パイプラインの中核 — 他のコマンドと
|で繋いで使うのが基本 - ほぼ全ての Linux にプリインストール済み — サーバー上でも即使える
- 正規表現で柔軟な検索 — 単純な文字列から複雑なパターンまで対応
- 軽量で高速 — 巨大なログファイルでもストレスなく動く
1973年に Ken Thompson が書いた ed エディタのコマンド g/re/p(global / regular expression / print)が語源だ。50年以上現役で使われ続けている。詳しくは GNU grep 公式マニュアルを参照。
基本的な使い方
まずは grep の基本オプションを押さえよう。これだけで日常の検索作業の大半は対応できる。
文字列検索
grep "error" logfile.txt
ファイル内の「error」を含む行がすべて表示される。
よく使うオプション
# 大文字小文字を無視して検索
grep -i "error" logfile.txt
# 行番号を表示
grep -n "error" logfile.txt
# ディレクトリを再帰的に検索
grep -rn "TODO" src/
# マッチしない行を表示(除外フィルタ)
grep -v "debug" logfile.txt
# マッチした行数をカウント
grep -c "error" logfile.txt
# マッチしたファイル名のみ表示
grep -l "error" *.log
コンテキスト表示
マッチした行の前後を表示したいときは -A(After)、-B(Before)、-C(Context)を使う。
# マッチした行の後ろ3行、前1行を表示
grep -A 3 -B 1 "error" logfile.txt
# 前後3行を表示(-A 3 -B 3 と同じ)
grep -C 3 "error" logfile.txt
複数パターン
# OR検索(拡張正規表現)
grep -E "error|warning|fatal" logfile.txt
# 固定文字列として検索(正規表現を無効化)
grep -F "console.log(" src/app.js
正規表現パターン
grep の真価は正規表現にある。基本正規表現(BRE)と拡張正規表現(ERE)の2種類があり、-E オプションで ERE を使える。正規表現の仕様は POSIX 正規表現仕様で定義されている。
よく使うパターン一覧
| パターン | 意味 | 例 |
|---|---|---|
^pattern | 行頭にマッチ | grep "^#" config.txt |
pattern$ | 行末にマッチ | grep "\.js$" files.txt |
. | 任意の1文字 | grep "h.t" words.txt |
[abc] | 文字クラス | grep "[0-9]" data.txt |
[^abc] | 否定文字クラス | grep "[^aeiou]" words.txt |
* | 直前の文字の0回以上 | grep "ab*c" data.txt |
+ (ERE) | 直前の文字の1回以上 | grep -E "[0-9]+" data.txt |
? (ERE) | 直前の文字の0回か1回 | grep -E "colou?r" text.txt |
\b | 単語境界 | grep -w "error" log.txt |
{n,m} (ERE) | n回以上m回以下 | grep -E "[0-9]{2,4}" data.txt |
BRE vs ERE
基本正規表現(BRE)では +、?、{}、|、() をメタ文字として使うにはバックスラッシュが必要だ。拡張正規表現(ERE: -E)ではそのまま使える。
# BRE: バックスラッシュが必要
grep "error\|warning" logfile.txt
grep "ab\{2,4\}" data.txt
# ERE: そのまま書ける(こちらが読みやすい)
grep -E "error|warning" logfile.txt
grep -E "ab{2,4}" data.txt
PCRE(Perl 互換正規表現)
-P オプションで Perl 互換の正規表現が使える。\d(数字)、\s(空白)、先読み・後読みなどが利用可能だ。
# 郵便番号パターン(3桁-4桁)
grep -P "\d{3}-\d{4}" addresses.txt
# メールアドレスっぽい文字列を抽出
grep -oP "[\w.+-]+@[\w-]+\.[\w.]+" contacts.txt
実践ユースケース
ログファイル解析
サーバー運用で最も使う場面だ。
# 特定期間のエラーを抽出(タイムスタンプ付きログ)
grep "2026-03-08.*ERROR" /var/log/app.log
# IPアドレスだけ抽出
grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" access.log
# HTTPステータスコード別に集計(grep + awk + sort の合わせ技)
grep -oE "HTTP/[0-9.]+ [0-9]+" access.log | awk '{print $2}' | sort | uniq -c | sort -rn
コードベース検索
大規模プロジェクトでの検索には find コマンドと組み合わせるとさらに柔軟になる。
# TODO/FIXME をプロジェクト全体から検索
grep -rn "TODO\|FIXME" --include="*.ts" src/
# 特定の関数呼び出し箇所を探す
grep -rn "useState(" --include="*.tsx" src/
# import文を検索(何をどこからインポートしているか)
grep -rn "^import.*from" --include="*.ts" --include="*.tsx" src/
設定ファイルフィルタリング
# コメント行と空行を除外して有効な設定だけ表示
grep -v "^#" /etc/ssh/sshd_config | grep -v "^$"
# 特定のセクションを抽出
grep -A 10 "\[database\]" config.ini
パイプラインでの活用
grep は単独でも使えるが、他のコマンドと組み合わせて真価を発揮する。xargs と繋げば、検索結果を次のコマンドの引数として渡せる。
# 実行中のnginxプロセスを確認(grep自身を除外)
ps aux | grep "[n]ginx"
# コマンド履歴からgit関連を検索
history | grep "git"
# カーネルメッセージからエラーを抽出
dmesg | grep -i "error"
# ファイル一覧から特定の拡張子だけフィルタ
find . -type f | grep "\.mdx$"
ripgrep:モダン代替
ripgrep(コマンド名: rg)は Rust で書かれた grep の代替ツールだ。Andrew Gallant(@BurntSushi)が開発し、GitHub で 50,000 以上のスターを獲得している。VS Code の内部検索エンジンにも採用されており、多くの開発者がデフォルトの検索ツールとして使っている。
主な特徴:
- 圧倒的な速度 — マルチスレッドで並列検索
- .gitignore 自動尊重 —
node_modulesやdistを勝手にスキップ - Unicode 完全対応 — 日本語でも問題なく検索できる
- バイナリファイル自動スキップ — 画像やコンパイル済みファイルを無視
- デフォルトで再帰検索 —
-rを付ける必要がない
インストール
winget install BurntSushi.ripgrep.MSVC
基本的な使い方
# カレントディレクトリ以下を再帰検索(-r 不要)
rg "TODO"
# ファイルタイプを指定して検索
rg "TODO" --type js
rg "TODO" -t py
# globパターンで対象ファイルを絞る
rg "TODO" -g "*.tsx"
# 固定文字列として検索(正規表現を無効化)
rg -F "console.log("
# 大文字小文字を無視
rg -i "error"
# 行番号は常に表示される(デフォルト)
rg "error" src/
高度な機能
# JSON形式で出力(他ツールとの連携に便利)
rg "error" --json
# 置換プレビュー(実際にはファイルを変更しない)
rg "old_func" -r "new_func"
# マッチした部分だけ表示(grepの -o に相当)
rg -o "\d{3}-\d{4}" addresses.txt
# 隠しファイルも検索対象に含める
rg --hidden "SECRET_KEY"
# .gitignore を無視して全ファイル検索
rg --no-ignore "password"
.rgignore で除外設定
プロジェクトルートに .rgignore ファイルを置くと、ripgrep 固有の除外設定ができる。書式は .gitignore と同じだ。
# .rgignore
dist/
coverage/
*.min.js
*.map
grep vs ripgrep
両方を理解した上で、使い分けの判断基準を整理する。
| 項目 | grep | ripgrep |
|---|---|---|
| 速度(大規模リポジトリ) | 単一スレッド | マルチスレッドで高速 |
| .gitignore | 無視する | 自動で尊重 |
| Unicode | 限定的 | 完全対応 |
| デフォルトの再帰検索 | -r が必要 | デフォルトで再帰 |
| バイナリファイル | 要オプションで除外 | 自動スキップ |
| 依存関係 | なし(標準搭載) | 別途インストール |
| PCRE サポート | -P で対応 | --pcre2 で対応 |
| カラー出力 | --color=auto | デフォルトでカラー |
使い分けの結論:
- サーバー上 — grep 一択。追加インストールなしで使える
- 開発マシン — ripgrep が圧倒的に快適。インストールして損はない
- シェルスクリプト — 移植性を考えるなら grep。自分の環境だけなら rg
両方の基本を覚えておけば、どんな環境でも困ることはない。grep で基礎を固め、ripgrep で生産性を上げるのがベストだ。
応用テクニック
ripgrep で複数行にまたがるパターンを検索する
--multiline(-U)オプションで、行をまたぐパターンにマッチできる。関数定義やマルチラインのログエントリを探すのに使える。
# 空の関数ブロックを検索
rg -U "function.*\{[\s]*\}" --type js
# try-catch ブロックを検索
rg -U "try\s*\{[\s\S]*?\}\s*catch" --type ts
ripgrep でカスタムファイルタイプを定義する
--type-add で独自のファイルタイプを定義できる。プロジェクト固有の拡張子がある場合に便利だ。
# MDX ファイルタイプを定義して検索
rg --type-add 'mdx:*.mdx' -t mdx "Callout"
# 設定ファイルタイプを定義(複数拡張子)
rg --type-add 'config:*.{conf,cfg,ini,toml,yaml,yml}' -t config "database"
dotfiles で export RIPGREP_CONFIG_PATH=~/.rgrc を設定すれば、カスタムタイプを永続化できる。
# ~/.rgrc
--type-add=mdx:*.mdx
--type-add=config:*.{conf,cfg,ini,toml,yaml,yml}
--smart-case
ripgrep で検索統計を表示する
--stats オプションで検索の統計情報(マッチ数、検索ファイル数、所要時間)を表示できる。大規模コードベースのリファクタリング前に影響範囲を把握するのに便利だ。
rg "deprecated_function" --stats
ripgrep + fzf でライブ検索する
ripgrep の検索結果を fzf で絞り込み、プレビュー付きでファイルを開くワンライナー。
# rg の結果を fzf でインタラクティブに絞り込み、vim で開く
rg --line-number --no-heading "TODO" | \
fzf --delimiter ':' \
--preview 'bat --color=always --highlight-line {2} {1}' \
--bind 'enter:execute(vim {1} +{2})'
FAQ
grep と ripgrep はどちらを使うべき?
開発マシンでは ripgrep を推奨する。.gitignore の自動尊重、マルチスレッド検索、Unicode 完全対応など、開発者にとって便利な機能がデフォルトで有効だ。一方、サーバー上やシェルスクリプトの移植性を重視する場面では grep が確実。両方覚えておくのがベスト。
macOS で grep -P が使えないのはなぜ?
macOS にプリインストールされているのは BSD grep であり、GNU grep ではない。-P(PCRE)は GNU grep 固有のオプションだ。brew install grep で GNU grep をインストールするか、ripgrep の --pcre2 オプションを使おう。
ripgrep で .gitignore を無視して全ファイル検索するには?
rg --no-ignore "パターン" で .gitignore の除外設定を無視できる。さらに隠しファイルも含めたい場合は rg --no-ignore --hidden "パターン" を使う。
grep で複数の条件を AND 検索するには?
grep 単体には AND 演算子がない。パイプで繋ぐのが定番だ: grep "条件1" file | grep "条件2"。ripgrep でも同様のアプローチが必要になる。
ripgrep の検索結果を置換に使えるか?
rg "old" -r "new" で置換プレビューができるが、実際にファイルは変更されない。ファイルを書き換えるには sed と組み合わせる: rg -l "old" | xargs sed -i 's/old/new/g'。
grep -r と grep -R の違いは?
-r はシンボリックリンクを辿らず、-R はシンボリックリンクを辿って再帰検索する。意図しないディレクトリに入り込むリスクを避けるため、通常は -r を使うのが安全だ。
ripgrep はどのエディタ・ツールと統合できる?
VS Code は内部検索エンジンとして ripgrep を採用している。Neovim の Telescope、Emacs の counsel-rg、fzf との連携も定番だ。IDE の検索が遅いと感じたら ripgrep ベースのプラグインを試す価値がある。
grep で日本語テキストを検索するときの注意点は?
GNU grep は --binary-files=text や -P で日本語を扱えるが、文字コードが UTF-8 でないファイルでは化ける場合がある。ripgrep は UTF-8 をデフォルトで扱い、BOM 付きファイルにも対応しているので日本語検索には ripgrep が無難だ。
まとめ
grep はテキスト検索の基本であり、Linux を使う限り避けて通れないコマンドだ。正規表現と組み合わせれば、ログ解析・コード検索・設定ファイルのフィルタリングなど、あらゆる場面で活躍する。
そして ripgrep は、grep の知識をそのまま活かしながら速度と利便性を大幅に向上させてくれる。.gitignore の自動尊重とマルチスレッド検索は、一度体験すると戻れなくなる。
次のステップとして、sed・awk で抽出した結果を加工する方法や、fzf と ripgrep を組み合わせたインタラクティブ検索も試してみてほしい。検索と加工を組み合わせることで、CLI での作業効率は飛躍的に上がる。
関連記事: