今さら聞けない grep 完全ガイド
はじめに
「grepくらい知ってるよ」と思いつつ、実は -o や -P を使いこなせていなかったり、正規表現の書き方が曖昧だったりしませんか?
この記事では grep の基本から実践的なテクニックまで体系的にまとめました。ブックマークしておくと、ふとした時に役立つはずです。
基本構文
grep [オプション] パターン [ファイル...]
まずはここから:基本の使い方
# ファイルから文字列を検索
grep "hello" file.txt
# 複数ファイルから検索
grep "hello" file1.txt file2.txt
# ディレクトリ内を再帰検索
grep -r "hello" ./src/
# パイプで標準入力から検索
cat file.txt | grep "hello"
ps aux | grep "nginx"
オプション早見表
検索の制御
| オプション | 意味 | 例 |
|---|---|---|
-i |
大文字小文字を無視 | grep -i "Hello" file.txt |
-w |
単語単位でマッチ | grep -w "is" file.txt |
-v |
マッチ しない 行を表示 | grep -v "debug" log.txt |
-E |
拡張正規表現を使用 | grep -E "err|warn" log.txt |
-F |
固定文字列として検索(高速) | grep -F "price=$100" file.txt |
-P |
Perl互換正規表現(Linux) | grep -P "\d{3}" file.txt |
出力の制御
| オプション | 意味 | 例 |
|---|---|---|
-n |
行番号を表示 | grep -n "error" log.txt |
-l |
マッチしたファイル名のみ | grep -rl "import" ./src/ |
-c |
マッチした行数を表示 | grep -c "error" log.txt |
-o |
マッチした部分のみ表示 | grep -o "http[^ ]*" file.txt |
-q |
出力なし(終了コードのみ) | grep -q "error" log.txt |
コンテキスト表示
| オプション | 意味 | 例 |
|---|---|---|
-A N |
マッチ行の 後 N行も表示 | grep -A 3 "error" log.txt |
-B N |
マッチ行の 前 N行も表示 | grep -B 3 "error" log.txt |
-C N |
マッチ行の 前後 N行を表示 | grep -C 3 "error" log.txt |
ファイルの絞り込み
| オプション | 意味 | 例 |
|---|---|---|
-r / -R
|
ディレクトリを再帰検索 | grep -r "TODO" ./src/ |
--include |
対象ファイルを限定 | grep -r --include="*.py" "def" . |
--exclude |
特定ファイルを除外 | grep -r --exclude="*.log" "error" . |
--exclude-dir |
特定ディレクトリを除外 | grep -r --exclude-dir=node_modules "import" . |
正規表現をマスターする
基本正規表現(BRE)— デフォルト
grep "^start" file.txt # 行頭が "start"
grep "end$" file.txt # 行末が "end"
grep "col.r" file.txt # . は任意の1文字(color, colar 等)
grep "ab*c" file.txt # b が0回以上(ac, abc, abbc...)
grep "a\{2,4\}" file.txt # a が2〜4回繰り返し
拡張正規表現(ERE)— -E オプション
grep -E "error|warning" log.txt # OR(どちらか)
grep -E "ab+c" file.txt # b が1回以上
grep -E "ab?c" file.txt # b が0回か1回
grep -E "(foo|bar)baz" file.txt # グループ化
grep -E "[0-9]{1,3}\.[0-9]{1,3}" f # IPアドレスの一部
文字クラス
grep "[aeiou]" file.txt # 母音のいずれか
grep "[0-9]" file.txt # 数字
grep "[^0-9]" file.txt # 数字以外
grep "[A-Za-z_]" file.txt # 英字またはアンダースコア
BRE と ERE の違いで混乱しがちなポイント:
- BRE では
\{,\},\(,\)とエスケープが必要 - ERE(
-E)では{,},(,)をそのまま使える -
|(OR)も BRE では\|、ERE ではそのまま|
迷ったら -E を常につける のが楽です。
実践レシピ集
ログ解析
# エラー行を抽出
grep -E "ERROR|FATAL" /var/log/app.log
# エラー件数をカウント
grep -c "ERROR" /var/log/app.log
# OutOfMemory の前5行を確認(原因調査)
grep -B5 "OutOfMemory" /var/log/app.log
コードベース検索
# React hooks の使用箇所
grep -rn --include="*.js" "useState" ./src/
# os モジュールを使っているファイル一覧
grep -rl --include="*.py" "import os" ./
# TODO / FIXME / HACK コメントを一括検索
grep -rn -E "TODO|FIXME|HACK" ./src/
不要行の除外
# コメント行を除外
grep -v "^#" config.conf
# 空行を除外
grep -v "^$" file.txt
# コメントと空行の両方を除外
grep -v "^#" config.conf | grep -v "^$"
AND 条件(複数キーワードを含む行)
# パイプで AND
grep "error" log.txt | grep "database"
# 正規表現で AND(順序を問わない)
grep -E "error.*database|database.*error" log.txt
安全なファイル操作
# NUL 区切りで安全にファイル一覧を処理
grep -rlZ "pattern" . | xargs -0 ls -la
grep の亜種
| コマンド | 等価 | 用途 |
|---|---|---|
egrep |
grep -E |
拡張正規表現 |
fgrep |
grep -F |
固定文字列検索(正規表現なし、高速) |
egrep と fgrep は非推奨(deprecated)です。grep -E、grep -F を使いましょう。
スクリプトで使う:終了コード
| コード | 意味 |
|---|---|
0 |
マッチあり |
1 |
マッチなし |
2 |
エラー |
# if 文との組み合わせ(-q で出力を抑制)
if grep -q "error" log.txt; then
echo "エラーが見つかりました"
fi
パフォーマンス Tips
-
固定文字列なら
-F— 正規表現の解析をスキップするので速い -
--include/--exclude-dirで検索範囲を絞る — 不要なファイルを読まない -
大規模リポジトリには
ripgrep(rg) — grep 互換で圧倒的に高速
おわりに
grep は地味ですが、使いこなせると日常の開発効率が確実に上がります。特に -E(拡張正規表現)、-o(マッチ部分のみ)、-C(コンテキスト表示)あたりは覚えておくと便利です。
「こんな使い方もあるよ」という Tips があれば、ぜひコメントで教えてください。