MENU

複数ファイルの中から特定の文字列を含むものを素早く探す方法

「このIPアドレスはどの設定ファイルに書いてあるのか」「このユーザー名がどのファイルに含まれているか」——サーバー移行やアカウント整理の際に必ず発生する調査です。ファイルを1つずつ開いて目視確認していては日が暮れます。

目的はシンプルです。指定した文字列を含むファイルを、ディレクトリ全体から素早く列挙すること。最短のコマンドを先に示します。

目次

まず結論:このコマンドで解決する

現代のLinux環境(RHEL系・Debian系・Ubuntu問わず)では、grep-r(再帰)オプションが最も手軽です。

# ファイル名だけ列挙(-l はリスト表示の意)
grep -rl "検索したい文字列" /対象ディレクトリ

# ファイル名・行番号・行内容をあわせて表示
grep -rn "検索したい文字列" /対象ディレクトリ

たとえばサーバーのIPアドレス 192.168.1.100 がどの設定ファイルに書かれているかを /etc 配下から探す場合は次のようになります。

# /etc 配下には一般ユーザーが読めないファイルがあるため sudo で実行
sudo grep -rl "192.168.1.100" /etc

出力例:

/etc/NetworkManager/system-connections/eth0.nmconnection
/etc/hosts

これだけで「どこに書かれているか」が一発で判明します。行の内容も確認したい場合は -l を外すと、ファイル名・行番号・マッチした行がセットで表示されます。

find と組み合わせる方法との使い分け

古くからある書き方として find … | xargs grep の組み合わせもあります。

find /対象ディレクトリ -type f -print0 | xargs -0 grep -l "検索したい文字列"

単純な文字列検索なら grep -r で十分ですが、find との組み合わせは次の場面で力を発揮します。

  • 拡張子でフィルターしたい(例:.conf ファイルだけ対象にする)
  • 更新日時で絞り込みたい(例:30日以内に変更されたファイルだけ)
  • ファイルサイズで除外したい(例:1MB超のファイルはスキップ)
# .conf ファイルだけを対象にして検索
find /etc -type f -name "*.conf" -print0 | xargs -0 grep -l "192.168.1.100"

# 30日以内に変更されたファイルだけを対象にする
find /etc -type f -mtime -30 -print0 | xargs -0 grep -l "192.168.1.100"

ファイル名にスペースや特殊文字が含まれる環境では xargs が誤動作することがあります。-print0 | xargs -0 と null 文字区切りにすることで回避できます。迷ったら grep -r --include="*.conf" のほうがシンプルです。

実務でよく使う絞り込みオプション

基本コマンドに以下を組み合わせると、調査の精度が上がります。

# 大文字・小文字を区別しない(-i)
grep -ril "error" /var/log

# バイナリファイルを検索対象から除外(-I)
grep -rlI "検索文字列" /usr/local

# 拡張子を指定して絞り込む(--include)
grep -rl "検索文字列" /etc --include="*.conf"

# 特定のディレクトリを除外する(--exclude-dir)
grep -rl "検索文字列" /var --exclude-dir={log,cache,run}

-I(大文字のアイ)はバイナリファイルへのマッチを抑制します。/usr/lib 配下など実行ファイルが混在するディレクトリを検索するときに付けると、余分な出力が大幅に減ります。

ホームディレクトリ配下を検索する実例

ある運用現場では、退職したユーザーのアカウント名が設定ファイルや履歴にどれだけ残っているかを棚卸しする作業が発生しました。そのときのコマンドが次のような形です。

# /home/olduser 配下で "olduser" を含むファイルを列挙
grep -rl "olduser" /home/olduser

# 出力例
# /home/olduser/.bashrc
# /home/olduser/.bash_history
# /home/olduser/.config/someapp/settings.conf

ファイル一覧が得られたら、そのまま xargs に渡してマッチ箇所を一括確認できます。

# 見つかったファイルのマッチ行を行番号付きで連続表示
grep -rl "olduser" /home/olduser | xargs grep -n "olduser"

大量ファイルを扱うときの注意点と高速化

ルート(/)や /var など広い範囲を検索すると数万〜数十万ファイルにヒットして時間がかかります。/proc/sys/dev は仮想ファイルシステムであり、検索しても意味がないうえにフリーズに近い状態になることがあります。これらは必ず除外します。

# ルートから検索する場合は仮想 FS を除外する(rootで実行)
sudo grep -rl "検索文字列" / \
  --exclude-dir=/proc \
  --exclude-dir=/sys \
  --exclude-dir=/dev \
  --exclude-dir=/run

さらに高速化したい場合は ripgrep(rg が有効です。主要ディストリビューションの標準リポジトリに収録されており、同等の検索を grep -r より数倍〜十数倍速く完了します。

# インストール(Debian/Ubuntu系)
sudo apt install ripgrep

# インストール(RHEL 9系 / AlmaLinux / Rocky Linux)
sudo dnf install ripgrep

# 基本的な使い方は grep -r と同じ感覚で使える
rg "検索文字列" /対象ディレクトリ

# ファイル名のみ表示(grep -rl 相当)
rg -l "検索文字列" /対象ディレクトリ

rg はデフォルトで .gitignore の記述を尊重し、隠しファイルやバイナリを自動でスキップします。漏れなく全ファイルを検索したい場合は rg --no-ignore --hidden を明示してください。意図せず対象外になるファイルがある場合もここが原因です。

パーミッションエラーへの対処

一般ユーザーで /etc/root 配下を検索すると Permission denied が大量に出ることがあります。対処は2通りです。

# エラーメッセージだけを捨てる(標準エラーを /dev/null へ)
grep -rl "検索文字列" /etc 2>/dev/null

# 権限ごと解決したい場合は sudo で実行
sudo grep -rl "検索文字列" /etc

2>/dev/null はエラー出力を捨てるリダイレクトです。「Permission denied」が邪魔なときに使いますが、本来必要なエラーまで消えることがあるため、調査目的に限って使うのが無難です。根本的に読み取り権限が必要な検索は sudo で実行するほうが確実です。

設定ファイルを移行するたびに手作業で探していた現場では、このコマンドを習得してから移行前の依存関係確認が大幅に効率化されます。探す作業を自動化することで、本来の移行・変更作業に集中できるようになります。

<PR>この記事に関連するおすすめ書籍

新しいLinuxの教科書 第2版

コマンド操作から基本的な運用までを手を動かしながら体系的に学べる定番書。地力を固めたい方に。

「コマンドは打てる。次は”現場で通用する型”を最短で身につけたい」——そんなあなたへ。

ネットの断片的なTipsをコピペするだけでは、体系的な運用スキルはなかなか積み上がりません。リナックスマスター.JPの無料メルマガ「リナマガ」では、現場で実際に使うLinuxサーバー運用の考え方を、順を追って実務目線でお届けしています。いま登録された方には、安全なサーバー構築の「型」をまとめた『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼント中です。

>> 図解60P『Linux入門マニュアル』を無料で受け取る
(メルマガ登録は10秒・いつでも解除OK)

※ 「独学の時間がもったいない」「プロから現場の技術を最短で学びたい」という本気の方には、2日で実務レベルが身につく初心者向けハンズオンセミナーもご用意しています。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

目次