「Linuxで特定のファイルを探したいけど、どこにあるかわからない…」
「フォルダが深くて、ひとつずつ探すのは大変…」
そんなときに役立つのが、再帰的にファイルを検索できるコマンドです。
実際に多くの場面で再帰的検索が必要になります:
「プロジェクト全体から特定の設定ファイルを見つけたい」
「システム全体で古いログファイルを一括削除したい」
「開発中のソースコードで特定の関数を使っているファイルを探したい」
「バックアップ前に重要なファイルの場所を確認したい」
「ディスク容量を圧迫している大きなファイルを特定したい」
この記事では、Linuxでの再帰的ファイル検索の基本から、高度な検索テクニック、実用的な活用例まで、初心者の方にもわかりやすく解説します。
再帰的検索の基本概念
再帰的検索とは
再帰的検索の定義
再帰的(recursive)検索とは、指定したディレクトリを起点として、その配下にあるすべてのサブディレクトリを順次たどりながら、目的のファイルやディレクトリを探索する方法です。
ディレクトリ構造の例
project/
├── src/
│ ├── main.c
│ ├── utils/
│ │ ├── helper.c
│ │ └── config.conf
│ └── tests/
│ └── test_main.c
├── docs/
│ ├── README.md
│ └── manual.pdf
└── logs/
├── app.log
└── error.log
再帰的検索の動作 上記の構造で project/
を起点に *.c
ファイルを検索すると:
project/
直下をチェックsrc/
内をチェック →main.c
を発見utils/
内をチェック →helper.c
を発見tests/
内をチェック →test_main.c
を発見docs/
とlogs/
内もチェック(該当なし)
Linuxでの検索コマンド比較
主要な検索コマンドの特徴
コマンド | 再帰検索 | 検索対象 | 実行速度 | 主な用途 |
---|---|---|---|---|
find | 標準で有効 | ファイル名・属性 | 中程度 | 汎用的なファイル検索 |
locate | システム全体 | ファイル名のみ | 高速 | インデックス化された検索 |
grep -r | オプションで有効 | ファイル内容 | 低速 | テキスト内容の検索 |
ls -R | 有効 | ディレクトリ一覧 | 高速 | ディレクトリ構造の表示 |
findコマンドによる基本的な再帰検索
findコマンドの基本構文
基本的な書式
find [検索開始パス] [検索条件] [アクション]
各要素の説明
- 検索開始パス:検索を開始するディレクトリ
- 検索条件:ファイル名、サイズ、日付などの条件
- アクション:見つかったファイルに対する処理
基本的な検索例
ファイル名による検索
# 現在のディレクトリ以下で memo.txt を検索
find . -name "memo.txt"
# /home/user 以下で memo.txt を検索
find /home/user -name "memo.txt"
# システム全体で memo.txt を検索(時間がかかる)
find / -name "memo.txt" 2>/dev/null
ワイルドカードを使った検索
# .txt で終わるファイルを検索
find . -name "*.txt"
# sample で始まるファイルを検索
find . -name "sample*"
# config という文字を含むファイルを検索
find . -name "*config*"
大文字・小文字を無視した検索
# -iname で大文字小文字を区別しない
find . -iname "*.JPG"
find . -iname "readme*"
高度な検索条件
ファイルタイプによる絞り込み
-typeオプションの活用
# ファイルのみを検索
find . -type f -name "*.log"
# ディレクトリのみを検索
find . -type d -name "*backup*"
# シンボリックリンクのみを検索
find . -type l
# 実行可能ファイルのみを検索
find . -type f -executable
ファイルタイプの種類
タイプ | 説明 | 使用例 |
---|---|---|
f | 通常ファイル | -type f |
d | ディレクトリ | -type d |
l | シンボリックリンク | -type l |
s | ソケット | -type s |
p | 名前付きパイプ | -type p |
b | ブロックデバイス | -type b |
c | キャラクターデバイス | -type c |
サイズによる検索
ファイルサイズでの絞り込み
# 100MB以上のファイルを検索
find . -type f -size +100M
# 1KB未満のファイルを検索
find . -type f -size -1k
# ちょうど1GBのファイルを検索
find . -type f -size 1G
# 空のファイル(0バイト)を検索
find . -type f -size 0
サイズ単位の指定
c
:バイトk
:キロバイト(1024バイト)M
:メガバイト(1024KB)G
:ギガバイト(1024MB)T
:テラバイト(1024GB)
日時による検索
更新時刻による検索
# 7日以内に更新されたファイル
find . -type f -mtime -7
# 30日以上前に更新されたファイル
find . -type f -mtime +30
# 今日更新されたファイル
find . -type f -mtime 0
# 1時間以内に更新されたファイル
find . -type f -mmin -60
日時オプションの種類
オプション | 対象時刻 | 単位 |
---|---|---|
-mtime | 更新時刻 | 日 |
-atime | アクセス時刻 | 日 |
-ctime | 属性変更時刻 | 日 |
-mmin | 更新時刻 | 分 |
-amin | アクセス時刻 | 分 |
-cmin | 属性変更時刻 | 分 |
権限による検索
ファイル権限での絞り込み
# 権限が755のファイルを検索
find . -type f -perm 755
# setuidビットが設定されたファイル
find . -type f -perm -4000
# 誰でも書き込み可能なファイル(セキュリティチェック)
find . -type f -perm -002
所有者による検索
# rootが所有者のファイルを検索
find . -user root
# 特定のグループが所有するファイル
find . -group wheel
# 所有者のいないファイル(孤立ファイル)
find . -nouser
複数条件の組み合わせ
論理演算子の使用
AND条件(-a または空白)
# .txt ファイルかつ100KB以上
find . -name "*.txt" -size +100k
# .log ファイルかつroot所有
find . -name "*.log" -user root
OR条件(-o)
# .txt または .md ファイル
find . -name "*.txt" -o -name "*.md"
# .jpg または .png ファイル
find . \( -name "*.jpg" -o -name "*.png" \)
NOT条件(!)
# .txt ファイル以外
find . ! -name "*.txt"
# ディレクトリ以外(つまりファイル)
find . ! -type d
複雑な条件の例
実用的な組み合わせ例
# 1週間以内に更新された.log ファイルで100MB以上
find . -name "*.log" -mtime -7 -size +100M
# .conf ファイルでrootが所有し、他者が書き込み可能
find . -name "*.conf" -user root -perm -002
# 画像ファイル(複数拡張子)で1年以上アクセスされていない
find . \( -name "*.jpg" -o -name "*.png" -o -name "*.gif" \) -atime +365
見つかったファイルに対するアクション
-execオプションによる処理
基本的な-exec使用法
# 見つかったファイルを詳細表示
find . -name "*.log" -exec ls -l {} \;
# 見つかったファイルの種類を確認
find . -name "*.conf" -exec file {} \;
# 見つかったファイルのサイズを表示
find . -name "*.tmp" -exec du -h {} \;
-execの構文説明
{}
:見つかったファイルのパスに置換される\;
:コマンドの終端を示す(重要)
一括処理の例
ファイルの削除
# 古いログファイルを削除(危険:事前確認必須)
find . -name "*.log" -mtime +30 -exec rm {} \;
# より安全な削除(確認付き)
find . -name "*.tmp" -exec rm -i {} \;
ファイルのコピー・移動
# バックアップディレクトリにコピー
find . -name "*.conf" -exec cp {} /backup/ \;
# 古いファイルをアーカイブディレクトリに移動
find . -name "*.old" -exec mv {} /archive/ \;
権限の一括変更
# 設定ファイルの権限を600に変更
find . -name "*.conf" -exec chmod 600 {} \;
# ディレクトリの権限を755に変更
find . -type d -exec chmod 755 {} \;
-exec の代替オプション
-delete オプション
# ファイルを直接削除(-exec rm より高速)
find . -name "*.tmp" -delete
# 空のディレクトリを削除
find . -type d -empty -delete
-print0 と xargs の組み合わせ
# ファイル名に空白が含まれる場合の安全な処理
find . -name "*.txt" -print0 | xargs -0 ls -l
# 大量のファイルに対する効率的な処理
find . -name "*.log" -print0 | xargs -0 gzip
grep との組み合わせ
ファイル内容の検索
基本的な内容検索
# .conf ファイル内で "Listen" を含む行を検索
find . -name "*.conf" -exec grep -l "Listen" {} \;
# .c ファイル内で "main" 関数を含むファイルを検索
find . -name "*.c" -exec grep -l "main" {} \;
より効率的な方法
# grep -r を使用(findより高速な場合がある)
grep -r "error" . --include="*.log"
# find と grep の組み合わせ(条件が複雑な場合)
find . -name "*.py" -mtime -7 -exec grep -l "import sys" {} \;
内容検索の高度な活用
複数パターンの検索
# 複数のキーワードを含むファイル
find . -name "*.conf" -exec grep -l "database\|mysql\|postgresql" {} \;
# 正規表現を使った検索
find . -name "*.log" -exec grep -E "ERROR|FATAL|CRITICAL" {} \;
コンテキスト付きの表示
# 見つかった行の前後も表示
find . -name "*.conf" -exec grep -A 2 -B 2 "Listen" {} \;
# ファイル名と行番号付きで表示
find . -name "*.py" -exec grep -n "def main" {} \;
実用的な活用例
システム管理での活用
ディスク容量の調査
# 大きなファイルを見つける
find / -type f -size +1G 2>/dev/null | head -10
# ディスク使用量の多いディレクトリを特定
find /home -type f -exec du -h {} \; | sort -hr | head -20
セキュリティ監査
# setuidファイルの検索(セキュリティリスク)
find / -type f -perm -4000 2>/dev/null
# 他者が書き込み可能なファイル
find / -type f -perm -002 2>/dev/null
# 最近変更されたシステムファイル
find /etc -mtime -1 -type f 2>/dev/null
ログ管理
# 古いログファイルの一覧
find /var/log -name "*.log" -mtime +30
# 大きなログファイルの圧縮
find /var/log -name "*.log" -size +100M -exec gzip {} \;
# ログローテーション後のクリーンアップ
find /var/log -name "*.log.*" -mtime +7 -delete
開発作業での活用
ソースコード管理
# 特定の関数を使用しているファイル
find . -name "*.c" -exec grep -l "malloc" {} \;
# コメントアウトされたコードの検索
find . -name "*.py" -exec grep -l "^#.*TODO\|^#.*FIXME" {} \;
# 大きなソースファイルの特定
find . -name "*.java" -size +50k
プロジェクト整理
# バックアップファイルの削除
find . -name "*~" -o -name "*.bak" -delete
# コンパイル済みファイルの削除
find . -name "*.o" -o -name "*.pyc" -delete
# 空のディレクトリの削除
find . -type d -empty -delete
パフォーマンスの最適化
検索速度の向上
検索範囲の限定
# 特定のディレクトリを除外
find . -path "./node_modules" -prune -o -name "*.js" -print
# 複数のディレクトリを除外
find . \( -path "./.*" -o -path "./node_modules" \) -prune -o -name "*.txt" -print
効率的な条件指定
# ファイルタイプを先に指定(高速化)
find . -type f -name "*.log"
# 日時条件を先に指定
find . -mtime -7 -name "*.tmp"
大量ファイル処理の最適化
xargs との効率的な組み合わせ
# 一度に複数ファイルを処理
find . -name "*.txt" | xargs wc -l
# 並列処理で高速化
find . -name "*.log" | xargs -P 4 gzip
メモリ効率の改善
# 大量のファイルを段階的に処理
find . -name "*.log" -print0 | xargs -0 -n 100 ls -l
エラー処理とトラブルシューティング
よくあるエラーと対処法
Permission denied エラー
# エラーメッセージを非表示
find / -name "*.conf" 2>/dev/null
# 権限のあるディレクトリのみ検索
find /home -name "*.txt" 2>/dev/null
検索結果が多すぎる場合
# 結果を制限
find . -name "*.log" | head -50
# ページング表示
find . -name "*.txt" | less
特殊文字を含むファイル名
# 安全な処理方法
find . -name "*.txt" -print0 | xargs -0 ls -l
デバッグと検証
検索条件のテスト
# 実際の削除前に確認
find . -name "*.tmp" -mtime +7 -print
# 条件の段階的確認
find . -name "*.log"
find . -name "*.log" -mtime +30
find . -name "*.log" -mtime +30 -size +100M
まとめ
Linuxでの再帰的ファイル検索の要点
検索目的 | 推奨コマンド | 特徴 | 使用場面 |
---|---|---|---|
基本的な名前検索 | find . -name "pattern" | シンプル・確実 | 日常的な作業 |
内容検索 | grep -r "pattern" . | 高速・内容重視 | テキスト検索 |
属性重視検索 | find . -type f -size +1M | 詳細条件 | システム管理 |
複合条件検索 | find . -name "*.log" -mtime +7 | 柔軟性 | 高度な管理作業 |
効率的な検索のポイント
- 条件の順序:より限定的な条件を先に指定
- 範囲の限定:不要なディレクトリの除外
- 適切なツール選択:目的に応じたコマンドの使い分け
- 安全な実行:削除等の操作前の確認
安全な運用のベストプラクティス
- 重要な操作前の事前確認(-print での検証)
- バックアップの作成
- 段階的な条件指定
- エラー出力の適切な処理
コメント