find でファイルを検索する

このレッスンで分かること

  • find は開始ディレクトリから条件に合うパスを再帰的に列挙します
  • 条件は -name -type -size -mtime -perm を AND / OR / 否定で組み合わせます
  • 最小例は find /tmp -name '*.log'

find でファイルを検索する とは

findコマンドを使い、ファイル名や条件を指定して目的のファイルを検索する操作を学びます。本レッスンでは、find でファイルを検索する の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。

なぜ重要か

サーバーにログインして「あのファイル、どこに置いたっけ」と探し回った経験は多くの開発者が一度はあるはずです。ホームディレクトリの奥深く、/var/log の下、コンテナイメージの中、どこにあるか分からないファイルを名前・拡張子・更新日時・サイズ・権限などの条件で網羅的にたどるのが find コマンドの仕事です。ls は今いるディレクトリ直下を覗くだけですが、find はディレクトリツリー全体を再帰的に走査し、条件に合うパスを 1 行ずつ出力します。シェルから直接使うのはもちろん、xargs-exec と組み合わせると一括削除・一括処理ができ、自動化スクリプトの中核として頻出します。

基本構文

ターミナル

find [検索開始ディレクトリ] [条件] [アクション]

検索開始ディレクトリを省略するとカレントディレクトリ (.) が使われます。代表的な条件は次の通りです。

条件役割
-name パターンファイル名がパターンに一致
-iname パターン-name の大文字小文字を無視するバージョン
-type f / -type dファイル / ディレクトリのみ
-size +1M / -1kサイズ条件 (+ は超過、- は未満)
-mtime -7過去 7 日以内に更新
-mmin -10過去 10 分以内に更新
-perm 644権限が 644
-maxdepth N階層を N に制限

動作の図解

diagram (will load when visible)

図の流れを順序リストで書き直すと、次の通りです。

  1. find /home/home を開始地点として走査を開始する
  2. ディレクトリツリーを深さ優先で下る
  3. 各ファイルに対して条件式を評価する
  4. 一致したファイル (例 notes.txtdiary.txt) を出力する
  5. 全パスを評価し終えたら終了

find は開始地点から深さ優先でツリーを下り、条件式を 1 ファイルずつ評価して、一致したパスだけを出力します。条件式は AND がデフォルトで、-o を挟むと OR! を前置すると否定になります。

代表例

名前で探す基本パターンです。

ターミナル

$ find /tmp -name '*.log' /tmp/app/error.log /tmp/app/access.log

更新日時とサイズを組み合わせて「最近作られた大きなファイル」を絞り込みます。

ターミナル

$ find /var/log -type f -mtime -1 -size +10M /var/log/journal/system@0.log

見つけたファイルに対してまとめてコマンドを実行する -exec も覚えておきましょう。{} がヒットしたパスに置換され、\; がコマンドの終端記号です。

ターミナル

$ find /tmp -name '*.tmp' -mtime +7 -exec rm -v {} \; removed '/tmp/old-cache.tmp'

大量のファイルに対しては -exec ... +xargs のほうが効率的です。+ は複数パスをまとめて 1 コマンドに渡します。

ターミナル

$ find /tmp -name '*.tmp' -print0 | xargs -0 rm -v

よくある間違い

-name のパターンはシェルではなく find が解釈します。シェルがワイルドカードを先に展開しないよう、必ずクォートで囲ってください。find . -name *.txt はカレントに a.txt だけがあると find . -name a.txt に展開され、サブディレクトリの *.txt がヒットしません。

-exec rm を試す前に、まず -print で対象を確認するのが鉄則です。条件式の組み立てを誤ると意図しないファイルを消し去ってしまいます。dry-run の文化を find でも徹底しましょう。

やってみよう

/tmp/findlab 配下にファイルを散らばらせ、*.log だけを抜き出す演習に挑戦してください。-name-type を組み合わせるのがコツです。

より実践的な使い方

複数条件を OR で組み合わせる

-o を使うと OR 条件になります。優先順位が必要なら括弧でグループ化しますが、シェルで括弧はメタ文字なのでエスケープが必要です。

ターミナル

$ find /tmp \( -name '*.log' -o -name '*.tmp' \) -type f /tmp/app/error.log /tmp/old-cache.tmp

結果を別コマンドへ受け渡す

ファイル数を数えたい、別ディレクトリへコピーしたい、git で追跡したい、いずれも -print0xargs -0 を組み合わせるのが安全です。空白を含むファイル名でも壊れません。

ターミナル

$ find . -type f -name '*.md' -print0 | xargs -0 wc -l 120 ./README.md 45 ./docs/setup.md

権限と所有者で絞り込む

セキュリティ調査でよく使う組み合わせです。

ターミナル

$ find /var/www -type f -perm -o=w

上記は「others に書き込み権限がある」ファイルを抽出します。意図しない chmod 777 が紛れていないかを点検できます。

この章のポイント

ここまでの要点 find 開始 条件 アクション。パターンはクォートで囲む。-exec rm の前に -print で確認、大量処理は -print0 | xargs -0 でスペース安全。

まとめ

  • find は開始ディレクトリから条件式を満たすパスを再帰的に列挙する
  • 条件式は -name-type-size-mtime-perm などを AND / -o / ! で組み合わせる
  • 危険な操作は -print で対象を可視化してから -execxargs で一括処理する
  • 大量ファイルに対しては -exec ... +xargs -0 のほうが速い
  • 空白を含むファイル名に備えて -print0xargs -0 をペアで使う

次のレッスン

次は ワイルドカードとグロブパターン で、findコマンドを使い、ファイル名や条件を指定して目的のファイルを検索する操作を学びます を学びます。

事前確認 — 進む前に次の 3 つができることを確認しましょう。

  1. find コマンド の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. find コマンド とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

課題

  1. find コマンドを使う
  2. -type f -name '*.log' で条件指定する
  3. sort で出力順を安定させる

ヒント

script.sh
script.sh
学習モード
script.sh
ターミナル出力