UNIX/Linuxの部屋 findコマンドの使い方

TOP UNIX/Linuxの部屋 UNIX/Linuxコマンド一覧 用語集 新版 由来/読み方辞書 環境変数マニュアル Cシェル変数 システム設定ファイル システムコール・ライブラリ ネットワークプログラミングの基礎知識 クラウドサービス徹底比較・徹底解説




コマンド find ファイル名・タイムスタンプ・ファイルサイズなどを元に、ファイル・ディレクトリを検索する。 このエントリーをはてなブックマークに追加

最終更新


UNIX/Linux の find コマンドは、ファイル名・タイムスタンプ・ファイルサイズ・オーナー・グループ・ファイルタイプなどを元に、ファイルやディレクトリを検索するコマンドである。AND・OR の組み合わせや正規表現が使えたり、検索だけではなくコマンドの実行も可能など、非常に強力なコマンドである。

目次:
  1. find コマンドの基本的な使い方
  2. 注意
  3. 検索開始ディレクトリ
  4. 検索条件オプション ファイル名 (-name/-path/-regex)
  5. 検索条件オプション タイムスタンプ・日付 (-mtime/-newer/-newerXY/-daystart)
  6. 検索条件オプション ユーザ・グループ (-uid/-group/-nouser)
  7. 検索条件オプション 階層系 (-maxdepth/-mindepth/-prune)
  8. 検索条件オプション ファイルサイズ (-size/-empty)
  9. 検索条件オプション パーミッション (-perm)
  10. 検索条件オプション ファイルタイプ (-type)
  11. 検索条件オプション i-node (-inum)
  12. 条件の結合・否定などのオプション (AND 条件・OR 条件・NOT)
  13. アクション: ファイル名・情報表示 (-print/-ls/-printf/-ok)
  14. アクション: コマンド実行 (-exec)
  15. アクション: その他 (-delete)
  16. いろいろなアクションの実行例:
  17. Howto: Permission denied などのエラーを抑止するには
  18. Howto: 複数のディレクトリを起点として検索するには
  19. Howto: ファイルまたはディレクトリのみを対象とする (-type f や -type d)
  20. Howto: 特定の拡張子のみ対象とする or 特定の拡張子を除外するには
  21. Howto: 特定のファイル名・ディレクトリ名を除外するには
  22. Howto: ファイル名について大文字小文字を区別せずに検索するには
  23. Howto: 改行コード CRLF を含むファイルを検索する
  24. Howto: ファイルをタイムスタンプでソートする
  25. find と xargs の組み合わせ
  26. find の -or オプションに括弧が必要な理由
  27. 注意点: csh・tcsh における -exec {} のエスケープ
  28. 関連コマンド


find コマンドの基本的な使い方
find コマンドの基本的な使い方は、下記のとおりである。
% find 検索開始ディレクトリ 検索条件 アクション

特定のディレクトリ以下の、ファイル・ディレクトリ一覧を表示するには -print オプションを指定する。
% find / -print
→ ルートディレクトリからマシン内の全ファイルの一覧を表示する
% find . -print
→ カレントディレクトリ以下の全ファイルの一覧を表示する
% find /usr/local -print
→ カレントディレクトリ以下の全ファイルの一覧を表示する

-name オプションを使うと、特定のファイル名のみを対象とする。
% find . -name '*.txt' -print
→ カレントディレクトリ以下の "*.txt" にマッチするファイルを全て表示sる

-print ではなく -ls オプションを使うと、ls -l のような表示になる。
% find . -name '*.txt' -ls
   39     17 drwxr-xr-x   25 root    wheel   111 Aug 22  2018 /etc
  656      9 -rw-r--r--    1 root    wheel  1993 Sep 29  2018 /etc/devfs.conf
  708      9 -rw-r--r--    1 root    wheel   113 Sep 29  2018 /etc/csh.cshrc
  645     17 drwxr-xr-x    2 root    wheel    10 Sep 29  2018 /etc/mtree

検索したファイル・ディレクトリに対し、-exec オプションで任意のコマンドを実行することができる。
% find . -name '*~' -exec rm {} \;
→ カレントディレクトリ以下の ~ で終わるバックアップファイルを rm コマンドで削除する

find コマンドの結果と grep コマンドを組み合わせることで、特定ファイル内容からの文字列検索ができる
% grep hoge `find . -name '*.txt'`
→ カレントディレクトリ以下の *.txt から hoge という文字列を検索
% find . -name '*.txt' | xargs grep hoge /dev/null
→ 対象ファイル名が多くても大丈夫な書き方

注意
find は、OS によって使用可能なオプションが大きく異なる。最も高機能な find は、Linux で使用されている GNU find であろう。*BSD の find も、GNU find の機能を積極的に取り込んでいる。一方、Solaris や HP-UX の find は、ここにあげたオプションの半分以上は使用できない。使っている OS のマニュアルでの確認を忘れずに。

検索開始ディレクトリ
検索を開始する起点のディレクトリを指定する
% find /foo/bar -type f -print
⇒ /foo/bar 以下の全ファイルの一覧を表示
% find . -type f -print
⇒ カレントディレクトリ以下の全ファイルの一覧を表示
検索開始ディレクトリは複数指定することも可能である。
% find /usr/local /usr/bin /usr/sbin -type f -print
⇒ /usr/local と /usr/bin と /usr/sbin 以下の全ファイルを表示
find は「検索開始ディレクトリ」以下のディレクトリを再帰的に検索する。よって、
% find / ...
は、そのマシン内の全ファイルを対象に検索することになる。

なお、カレントディレクトリにディレクトリ dir/ が存在する場合、下記のようにすると ./dir 以下が 2重でリストアップされることに注意。
% find . ./dir

FreeBSD・Linux など一部の find では、検索開始ディレクトリのみを指定すると、コマンドとして -print が指定されたものとして動作する。
% find /usr

また、Linux などの GNU find では下記のように検索開始ディレクトリの省略も可能。この場合カレントディレクトリが検索開始ディレクトリとみなされる。
% find

検索条件オプション ファイル名 (-name/-path/-regex)
▷ -name [glob文字列]
検索するファイル名・ディレクトリ名を指定する。指定するファイル名は部分一致ではなく完全一致であることに注意しよう。
% find . -name foo.txt -print
→ 「foo.txt」というファイルまたはディレクトリを検索する。「foo.txt.bak」はヒットしない。
% find . -name mydir -print
→ 「mydir」というファイルまたはディレクトリを検索する。「mydir2」はヒットしない。
ワイルドカードとして *・?・[・] を使用することが可能だが、その場合は "" などで囲んだり、エスケープしよう。
% find . -name "*abc*"
→ 名前のどこかに "abc" を含むファイルまたはディレクトリを検索する。
% find . -name \*abc\*
→ \ でエスケープしてもよい。
ワイルドカードでは足りない複雑な条件の場合、より強力な -regex で正規表現で指定するとよい。

-name は、「最後のパス部分のみ」が検索対象であることに注意。カレントディレクトリ以下に
abc.txt
xxx/
xxx/abc.txt
abc/
abc/def.txt
というファイル・ディレクトリがあるとき、
% find . -name "*abc*"
とすると、abc.txt と abc/ と xxx/abc.txt はマッチするが、abc/def.txt はマッチしない。なぜなら abc/def.txt の最後のパス部分は "def.txt" であるため、"*abc*" と一致しないからである。

よって、-name オプションで「指定のディレクトリ名以下のファイル一覧」を表示することはできない。その場合は -path や -regex を使うこと。
▷ -iname [glob文字列]
検索するファイル名を指定。大文字小文字を区別しない以外は -name と同じ。
▷ -path [glob文字列]
-name と似ているが、「最後のパス部分のみ」ではなく「パス全体」を対象に検索する。下記は「ディレクトリ名・ファイル名のどこでもよいから "hoge" が含まれるもの」をリストアップする。
% find ./ -path "*hoge*"
よって、下記のすべてが対象となる (-name "*hoge* の場合、"./hoge/abc.def" は対象とならない)。
./hoge
./hoge/abc.def
./xxx/hoge.txt
▷ -ipath [glob文字列]
検索するパスを指定。大文字小文字を区別しない以外は -ipath と同じ。
▷ -regex reg
パスを含むファイル名全体が正規表現 reg にマッチするものを検索する。-name と異なり、検索対象がパスも含むことに注意。また、「〜を含む」ではなく、「全体がマッチする」という条件であることにも注意。例えば
% find . -regex "abc"
は絶対にマッチしない。なぜなら、カレントディレクトリに abc というファイルがあった場合は「./abc」と出力されるが、これは -regex で指定した正規表現「abc」とマッチしないからである。この場合は下記のようにしなければならない。
% find . -regex ".*abc.*"
▷ -iregex reg
大文字小文字を区別しない以外は、-regex と同じ。

検索条件オプション タイムスタンプ・日付 (-mtime/-newer/-newerXY/-daystart)
タイムスタンプや日付・日時をキーとしてファイル・ディレクトリを検索する方法を説明する。
伝統的な UNIX でも *BSD でも Linux でも使えるのは -mtime や -newer ではあるが、なにしろ大変わかりづらい。-mtime オプションなどは仕様すら異なる。

FreeBSD や Linux などの GNU ベースの find 限定ではあるが、おすすめは -newermt オプションで、-newermt '2017-05-26' や -newermt '2017-05-26 19:01:12' などとわかりやすく日付や時刻を指定することができる。

▷ -mtime [+-]n
mtime オプションを使うと、n日前に修正されたファイルを検索することができる。日数にプラスマイナスをつけることで、N日以前・N日以後・N日より前、などの条件をつけることができる。驚くことに、BSD の find と GNU の find で、mtime +N の意味が異なるようだ。要注意である。
-mtime 1 1日前 (24時間前〜現在) に修正されたファイル
-mtime 2 2日前 (48時間前〜24時間前) に修正されたファイル
(BSD find)-mtime +0 現在より前に修正されたファイル
(BSD find)-mtime +1 1日前 (24時間前) より前に修正されたファイル
(GNU find)-mtime +0 1日前 (24時間前) より前に修正されたファイル
(GNU find)-mtime +1 2日前 (48時間前) より前に修正されたファイル
-mtime -0 現在より後に修正されたファイル
-mtime -1 1日後 (24時間後より後) に修正されたファイル

UNIXのタイムスタンプ全般についてはタイムスタンプの項を参照。
▷ -atime [+-]n
n日前にアクセスされたファイル。それ以外は mtime と同じ。
▷ -ctime [+-]n
n日前にファイルステータスが変更されたファイル。それ以外は mtime と同じ。
▷ -newer file
ファイル file よりタイムスタンプが新しいファイル・ディレクトリを検索。タイムスタンプ比較用ファイルをあらかじめ作成し、touch コマンドを使ってタイムスタンプを変更し、そのファイルと比較するとよい。"newer" なので、比較対象ファイルより「新しいもの」を検索することに
注意 (同じタイムスタンプはマッチしない)。

逆に、「〜より古い」という条件で検索したい場合は、条件の否定を使う。
% find . \! -newer file -print
▷ -newermt 'YYYY-MM-DD' または -newermt 'YYYY-MM-DD HH:MM:SS'
指定した日付・時刻よりも新しいファイル・ディレクトリを検索する。'YYYY-MM-DD' と日付のみを指定した場合は、'YYYY-MM-DD 00:00:00' と同じとなる。"newer" なので、この日付・時刻より「新しいもの」を検索することに注意 (同じタイムスタンプはマッチしない)。

% find . -newermt '2017-05-26'
→ 最終更新時刻が 2017-05-26 00:00:00 より新しいファイルを検索 (同じタイムスタンプは含まない)
% find . -newermt '2017-05-26 11:22:33'
→ 時分秒まで指定
% find . \! -newermt '2017-05-26'
→ 最終更新時刻が 2017-05-26 00:00:00 以前のもの (同じタイムスタンプも含む)
% find . -newermt '2017-05-26' \! -newermt '2017-05-28'
→ 最終更新時刻が 2017-05-26 00:00:00 より新しく、2017-05-28 00:00:00 以前のもの
▷ -newerXY [指定文字列]
上記ではよく使われると思われる -newermt オプションを紹介したが、実際は -newerXY というオプションの一例にすぎない。-newerXY とは何かを言葉で説明するとまず伝わらないと思うので、下記の -newerXY の全パターンを参考にしてほしい。
-newerat [日付]
最終アクセス時刻 (atime) が指定日付より新しいファイル
-newerct [日付]
最終ステータス変更時刻 (ctime) が指定日付より新しいファイル
-newermt [日付]
最終変更時刻 (mtime) が指定日付より新しいファイル
-newerBt [日付]
ファイル作成時刻 (birthtime) が指定日付より新しいファイル
-newerac a.txt
最終アクセス時刻 (atime) が a.txt の最終ステータス変更時刻 (ctime) より新しいファイル
-neweram a.txt
最終アクセス時刻 (atime) が a.txt の最終変更時刻 (mtime) より新しいファイル
-neweraB a.txt
最終アクセス時刻 (atime) が a.txt のファイル作成時刻 (birthtime) より新しいファイル
-newerca a.txt
最終ステータス変更時刻 (ctime) が a.txt の最終アクセス時刻 (atime) より新しいファイル
-newercm a.txt
最終ステータス変更時刻 (ctime) が a.txt の最終変更時刻 (mtime) より新しいファイル
-newercB a.txt
最終ステータス変更時刻 (ctime) が a.txt のファイル作成時刻 (birthtime) より新しいファイル
-newerma a.txt
最終変更時刻 (mtime) が a.txt の最終アクセス時刻 (atime) より新しいファイル
-newermc a.txt
最終変更時刻 (mtime) が a.txt の最終ステータス時刻 (ctime) より新しいファイル
-newermB a.txt
最終変更時刻 (mtime) が a.txt のファイル作成時刻 (birthtime) より新しいファイル
-newerBa a.txt
ファイル作成時刻 (birthtime) が a.txt の最終アクセス時刻 (atime) より新しいファイル
-newerBc a.txt
ファイル作成時刻 (birthtime) が a.txt の最終ステータス時刻 (ctime) より新しいファイル
-newerBm a.txt
ファイル作成時刻 (birthtime) が a.txt の最終変更時刻 (mtime) より新しいファイル
タイムスタンプの種類については、下記を参考にしてほしい。ただし、ファイル作成時刻 (B:birthtime) を使えるのは 2017/05 時点では FreeBSD 5.0-RELEASE 以降など、一部の環境と思われる。
▷ -daystart (GNU find のみ)
実行時の日付の 0時0分を起点として計算する。現在 10日の 20時である場合、下記は 10日の 0時0分を起点として、1日前である「9日の 0時0分〜23時59分」に更新されたファイルが対象となる。
% find . -daystart -mtime 1 -print

検索条件オプション ユーザ・グループ (-uid/-group/-nouser)
▷ -user ユーザ名またはUID
指定のユーザが所有するファイル・ディレクトリ等
▷ -group グループ名またはGID
指定のグループが所有するファイル・ディレクトリ等
▷ -nouser
/etc/passwd に載っていない UID が所有するファイル・ディレクトリ等
▷ -nogroup
/etc/group に載っていない GID が所有するファイル・ディレクトリ等
-nouser と -nogroup オプションは、削除済のユーザ・グループが所有していたファイル・ディレクトリが残っていないかの確認に使うとよい。

検索条件オプション 階層系 (-maxdepth/-mindepth/-prune)
▷ -maxdepth n
検索対象を n 階層に制限する。
% find / -maxdepth 0
/
⇒ 0 階層目 (指定した検索開始ディレクトリ) でストップ

% find / -maxdepth 1
/
/dev
/etc
(略)
⇒ 1 階層目でストップ。ただし 0階層目の / も表示されていることに注意。

% find / -maxdepth 2
/
/dev
/dev/network
(略)
/etc
/etc/defaults
(略)
⇒ 2 階層目でストップ。ただし 0・1階層目も表示されていることに注意。
▷ -mindepth n
n 階層以内のファイル・ディレクトリを表示しない。上位のディレクトリを対象外にしたい場合に有用。
% find / -mindepth 1
/dev
/dev/network
/dev/geom.ctl
(略)
⇒ / が表示されていないことに注意

% find / -mindepth 2
/dev/network
/dev/geom.ctl
(略)
⇒ / と /dev が表示されていないことに注意

-mindepth は、-maxdepth と組み合わせると有用である。
% find /usr -maxdepth 1 -mindepth 1 -type d
⇒ /usr 直下にあるディレクトリのみを表示。
▷ -prune
それ以上ディレクトリを降りない。特定のディレクトリ以下を除外する場合に有用。
% find . -prune -print
.
⇒ 単体で使用しても意味がない。
% find . -type d -name CVS -prune -o -print
⇒ CVS/ 以下を除外する。
% find /usr/* -type d -prune
⇒ /usr 直下にあるディレクトリのみを表示
実際は -prune はディレクトリ以外にも効果があるので、
% find . -name "*.txt" -prune -o -print
⇒ *.txt というファイルを除外する。
という使い方もできるが、これは
% find . \! -name "*.txt"
と同じである。

検索条件オプション ファイルサイズ (-size/-empty)
▷ -size [+-]n[ckMG]
ブロックサイズまたはファイルサイズで検索。「-size 100」だとブロックサイズとみなし、「-size 100c」などと末尾に c をつけるとファイルサイズとみなす。サイズの前に「+」「-」を付けることで、N以上・N以下を指定できる。
% find . -size 100c
⇒ ファイルサイズがちょうど 100 バイトのファイル・ディレクトリを検索
% find . -size +100c
⇒ ファイルサイズが 101 バイト以上のファイル・ディレクトリを検索
% find . -size -100c
⇒ ファイルサイズが 99 バイト以下のファイル・ディレクトリを検索

% find . -size 4
⇒ ブロックサイズが 4 のファイル・ディレクトリを検索
% find . -size +4
⇒ ブロックサイズが 5 以上のファイル・ディレクトリを検索
% find . -size -4
⇒ ブロックサイズが 3 以下のファイル・ディレクトリを検索
各ファイルのブロックサイズは ls -s で参照できる。

また、GNU find では「-size 100k」「-size 100M」「-size 100G」とすることで、キロバイト・メガバイト・ギガバイトの指定ができる (1k=1024バイト、1M=1,048,576バイト、1G=1,073,741,824バイト)。

+ - について、以上なのか超なのか、以下なのか未満なのかは未調査。なぜか BSD も GNU も、find のマニュアルに + - について言及がない。
▷ -empty
空のファイル、空のディレクトリの場合。具体的には
  • 「ファイルで、そのサイズがゼロ」
  • 「ディレクトリで、その下にファイル・ディレクトリ等がない」
のいずれかである。

検索条件オプション パーミッション (-perm)
パーミッションで検索する場合、-perm オプションを使う。指定方法が 3通りあるので、分けて説明する。
▷ -perm [パーミッション文字列]
絶対指定。[パーミッション文字列] に完全に一致するファイル・ディレクトリを検索する。

[パーミッション文字列] には 644 といった 8進数指定や、u=rw,g=r,o=r といったシンボルでの指定ができる。なお、u はオーナー、g はグループ、o はその他、である。a を使うとオーナー・グループ・その他をまとめて指定できる。

例えば、下記 3つはすべて同じ意味である。
% find . -perm 644 -ls
% find . -perm u=rw,g=r,o=r -ls
% find . -perm a=r,u+w -ls

以下の 8進数指定とそれに続くシンボル指定は、それぞれ同じ意味である。
% find . -perm 000 -ls
% find . -perm u=,g=,o= -ls
% find . -perm 644 -ls
% find . -perm u=rw,g=r,o=r -ls
% find . -perm 666 -ls
% find . -perm a=rw -ls
% find . -perm 755 -ls
% find . -perm u=rwx,g=rx,o=rx -ls
% find . -perm 777 -ls
% find . -perm a=rwx -ls
% find . -perm 4755 -ls
% find . -perm u=rwxs,g=rx,o=rx -ls
% find . -perm 2755 -ls
% find . -perm u=rwx,g=rxs,o=rx -ls
% find . -perm 1755 -ls
% find . -perm u=rwx,g=rx,o=rxt -ls

▷ -perm -[パーミッション文字列]
先頭にハイフンをつけることで AND 検索となる。パーミッション文字列で指定した全てのビットが立っているファイル・ディレクトリを検索する。-perm 644 形式とは異なり、指定していないビットが立っていても検索対象となる。

例えば下記は、「グループ」に書き込み権限があり、なおかつ (AND) 「その他」に書き込み権限があるファイル・ディレクトリを検索する。

また、022 以外のビットが立っているか否かは無関係なので、777 (rwxrwxrwx) や 666 (rw-rw-rw-) にもマッチする。AND 検索なので、707 (rwx---rwx) や 660 (rwxrwx---) にはマッチしない。
% find . -perm -022
% find . -perm -g=w,o=w

▷ -perm +[パーミッション文字列] または -perm /[パーミッション文字列]
先頭に + や / を付けることで OR検索となる。パーミッション文字列で指定したのビットがいずれかが立っているファイル・ディレクトリを検索する。-perm 644 形式とは異なり、指定していないビットが立っていても検索対象となる。

例えば下記は、「グループ」に書き込み権限があるか、または (OR) 「その他」に書き込み権限があるファイル・ディレクトリを検索する。

また、022 以外のビットが立っているか否かは無関係なので、777 (rwxrwxrwx) や 666 (rw-rw-rw-) にもマッチする。OR 検索なので、707 (rwx---rwx) や 660 (rwxrwx---) にもマッチする。
% find . -perm +022 -ls
% find . -perm +g=w,o=w -ls
下記は、全ファイルから setuid または setgid または sticky bit が立っているファイルを検索するものである。
% find / -perm +7000 -ls
% find / -perm +u=s,g=s,o=t -ls

なお、-perm +[パーミッション文字列] については仕様バグがあり、-perm +u+x としたとき、-perm +111 と -perm 111 の 2パターンの解釈ができてしまう。実装上は -perm 111 となるようである。(と GNU find のマニュアルには書いてある)。

そこで GNU find では -perm + に変わり -perm / という書き方を導入した。Linux など GNU find が使える環境では -perm / を使い、それ以外では -perm + を使うとよい。書式は下記のように -perm + を -perm / に変えるだけである。
% find . -perm /022 -ls
% find . -perm /g=w,o=w -ls

検索条件オプション ファイルタイプ (-type)
▷ -type [ファイルタイプ] ファイルの種類
-type オプションに続けて以下のようなファイルタイプを指定することで、ファイルのみ・ディレクトリのみ、などと特定のファイルタイプのみを選択できる。また、! や -not を使うことで、特定のファイルタイプを除外する。
% find . -type f
→ ファイルのみを検索する。
% find . -type d
→ ディレクトリのみを検索する。
% find . -type f or -type l
→ ファイルまたはシンボリックリンクを検索する。
% find . \! -type d
→ ディレクトリのみ除外する。

-type オプションで使用可能なファイルタイプを以下に示す。
b ブロックデバイス
c キャラクタデバイス
d ディレクトリ
f ファイル
l シンボリックリンク
p 名前付きパイプ
s ソケット (UNIX ドメインソケット)
D Door (Solaris のみ)

検索条件オプション i-node (-inum)
▷ -inum inode 番号
指定の inode のファイルまたはディレクトリ。inode は ls -i で確認できる。例えば、
% ls -l
-rw-r--r-- 1 user group 0 Jul 4 13:43 ???????????????
のように文字化けしたファイルができてしまった場合、
% ls -li
22327771 -rw-r--r-- 1 user group 0 Jul 4 13:43 ???????????????
として inode を確認した上で、下記のようにすれば削除したり、リネームしたりすることができる。
% find . -inum 22327771 -delete
→ 削除
% find . -inum 22327771 -ok mv {} abc.txt \;
→ abc.txt にリネーム

なお、コントロールコードを含むファイルは、例えば
% perl -e '$fn=pack("C*", 1..15);open(OUT, ">", $fn)'
などで作成可能である。これは 0x01〜0x0F というファイル名のファイルを生成する。

inode はファイルシステムごとの通番のような番号なので、複数のファイルシステムにまたがった場合は同じ inode が存在する可能性があることに注意。例えば、/・/usr・/home・/var という 4つのファイルシステムがマウントされている場合、
% find /usr -inum 100
であればファイルが 1つに特定できるが、
% find / -inum 100
とすると /・/usr・/home・/var それぞれの inode が 100 であるファイルが表示される可能性がある。

条件の結合・否定などのオプション (AND 条件・OR 条件・NOT)
▷ -a または -and オプション。-and は使えない環境もある。
検索条件を AND で結ぶ。
% find . -name abc -and -type d
⇒ abc という名前のディレクトリを検索
ただし、複数の検索条件を並べて書けば AND として扱われるので、上記コマンドは
% find . -name abc -type d
と同じ。
▷ -o または -or オプション。-or は使えない環境もある。
検索条件を OR で結ぶ。
% find . -name abc -or -name def
⇒ abc か def という名前のファイル・ディレクトリを検索
しかしながら、
% find . -name abc -or -name def -print
のように -print などのアクションを付けると def は表示されるが、abc は表示されないので、
% find . \( -name abc -or -name def \) -print
と -or 部分を括弧で囲うようにすればよい。この理由は こちら を参照。
▷ ! または -not オプション。-not は使えない環境もある。
他の条件の前に付けて、条件を否定する。-not は一部の find でしか使えない。
% find . \! -name \*.txt -print
⇒ 拡張子が .txt で *ない* ファイル・ディレクトリ
% find . -not -newer target.txt -print
⇒ target.txt とタイムスタンプが同じか、あるいは古いファイル・ディレクトリ

-a・-o・! は POSIX で規定されているが、-and・-or・-not はそうではない。-and・-or・-not は GNU find や FreeBSD では使用可能であるものの、Solaris の find では使用できない。

アクション: ファイル名・情報表示 (-print/-ls/-printf/-ok)
▷ -print 対象ファイル名を表示する。
% find . -name \*.txt -print
./sample.txt
./dir/sample2.txt
アクションが指定されていない場合、-print が使用されるため、下記はいずれも同じ結果となる。
% find . -name \*.txt -print
% find . -name \*.txt
▷ -ls 対象ファイルを詳しく (ls -l と同じように) 表示する。
より正確に言うと、行頭に inode と使用ブロックサイズが表示されるため、ls -lis と同じである。
▷ -printf これは GNU find のみで使用できるオプションだが、printf(3) のような書式でファイルの情報を表示することができる。
% find . -printf "%M %TY-%Tm-%Td %TH:%TM:%TS %p\n"
-rw-rw-r-- 2017-01-11 19:54:01.6838397390 ./.config/gcloud/.metricsUUID
drwxr-xr-x 2017-01-11 19:54:02.0138390000 ./google-cloud-sdk
-rw-r--r-- 2016-12-10 06:45:43.0000000000 ./google-cloud-sdk/path.bash.inc
-rw-r--r-- 2016-12-10 06:45:43.0000000000 ./google-cloud-sdk/path.zsh.inc
→ パーミッションと、タイムスタンプと、ファイル名を表示する例

アクション: コマンド実行 (-exec)
▷ -exec {} ; 検索ファイルを引数としてコマンドを実行する。
-exec の後にはコマンドを指定し、{} と書いた部分はそれぞれのファイル・ディレクトリ名に置換される。そしてコマンドの終了を示すために最後に ";" で終端する。
% find dir/ -name \*.txt -exec chmod 644 {} \;
→ dir/ 以下の *.txt について chmod 644 を実行する。
";" はシェルに解釈させずに find コマンドに渡す必要があるので、上記のように \; と書くか、あるいは ";" などと書いてエスケープする必要がある。{} と \; の間にはスペースが必要であることに注意。
▷ -exec {} + 検索ファイルを引数としてコマンドを一括実行する。
-exec {} ; は見つかったファイル・ディレクトリそれぞれについてコマンドを実行するが、-exec {} + は一括して処理を行う。
dir/file1.txt
dir/file2.txt
dir/subdir/file3.txt
が存在するとして、-exec {} ; を使って
% find dir/ -name \*.txt -exec chmod 644 {} \;
を実行すると、
% chmod 644 dir/file1.txt
% chmod 644 dir/file2.txt
% chmod 644 dir/subdir/file3.txt
が行なわれる。

一方、-exec {} + の場合は
% find dir/ -name \*.txt -exec chmod 644 {} +
とすると、
% chmod 644 dir/file1.txt dir/file2.txt dir/subdir/file3.txt
と 1回のみ実行される。
▷ -ok コマンド実行の前に確認を行う。
-ok は -exec と同じだが、実行する際に確認を求める。
% find dir/ -name \*.txt -ok chmod 644 {} \;
"chmod 644 dir/file1.txt"?
→ y を入力すると実際に実行される。それ以外はスキップ。
以下のように -ok {} + も使える。
% find dir/ -name \*.txt -ok chmod 644 {} +

アクション: その他 (-delete)
▷ -delete 対象ファイル・ディレクトリを削除する。
% find dir/ -delete
→ dir 以下 (dir も含む) の全ファイル・ディレクトリを削除する。
% find dir/ -name \*.txt -delete
→ dir 以下から、拡張子 txt のファイルを削除する。

いろいろなアクションの実行例:
アクションの例を以下に示す。
% find / -name .cshrc -print
⇒ ルートディレクトリ以下の .cshrc を検索してフルパスを表示する
% find /usr/local -name file\* -ls
⇒ /usr/local 以下の file* を検索して詳細な情報を表示する
% find . -name \*~ -exec rm {} \;
⇒ カレントディレクトリ以下の *~ をリストアップして rm コマンドで削除する。
% find . -name \*~ -print -exec rm {} \;
⇒ コマンドは複数個指定できる。
% find . -name \*~ -exec ls {} \; -exec rm {} \;
⇒ (この例はあまり意味はないが) -exec を複数個指定してもよい。

Howto: Permission denied などのエラーを抑止するには
他ユーザのディレクトリを検索する場合、読み込み権限のないディレクトリは permission denied と表示され、出力が見にくくなる。

sh・bash なら下記のように標準エラー出力 (ファイルディスクリプタ2) を捨てればよい。
% find / -name hoge\* -print 2>/dev/null

csh・tcsh は下記のようにすることで、標準エラー出力のみを捨てることができる。
% (find / -name hoge\* -print >/dev/tty ) >& /dev/null

Howto: 複数のディレクトリを起点として検索するには
以下のように複数のディレクトリを羅列すればよい。
% find /dir1 /dir2 /dir3 ....

Howto: ファイルまたはディレクトリのみを対象とする (-type f や -type d)
ファイルのみを検索対象とするには:
% find . -type f -print
ディレクトリのみを検索対象とするには:
% find . -type d -print

Howto: 特定の拡張子のみ対象とする or 特定の拡張子を除外するには
ファイル名やディレクトリ名が *.txt か *.sh のみ対象とするには下記のように -name を -o で結べばよい
% find dir/ \( -name \*.txt -o -name \*.sh \) -print
-regex を使う方法もあるが、残念ながら汎用的ではない。GNU find では、find デフォルトの正規表現は "emacs" であり、下記のように "(" ")" "|" をエスケープすれば使える。
% find dir/ -regex '.*\.\(txt\|sh\)' -print
しかしながら BSD の find は BRE (基本正規表現) であるので、"|" には「選択 (OR)」の意味がない。よって、BSD の find では上記の例はうまく動かない。

一方、特定の拡張子を除外するには以下のように ! や -not で否定したものを並べるか、-not -regex とする。この -regex も同様に BSD の find では動作しない。
% find dir/ -not -name \*.txt -not -name \*.sh -print
% find dir/ ! -name \*.txt ! -name \*.sh -print
% find dir/ -not -regex '.*\.\(txt\|sh\)' -print

Howto: 特定のファイル名・ディレクトリ名を除外するには
ファイル名やディレクトリ名が拡張子 bak、.svn、.DS_Store であった場合は除外するには、! か -not を使用する。
% find dir/ ! -name \*.bak ! -name .svn ! -name .DS_Store -print
% find dir/ -not -name \*.bak -not -name .svn -not -name .DS_Store -print

Howto: ファイル名について大文字小文字を区別せずに検索するには
-iname オプションを使うことで、file.txt にも FILE.TXT にもマッチする。正規表現を使いたい場合は -iregex を使う。
% find dir/ -iname file.txt

Howto: 改行コード CRLF を含むファイルを検索する
カレントディレクトリ以下から、改行コードが CRLF を含むファイル名の一覧を表示する例。
% find . -type f | xargs grep -lUPz '\r\n'
Linux・FreeBSD いずれも使えるはず。

Howto: ファイルをタイムスタンプでソートする
GNU find なら -printf オプションを使えばよい。
% find . -type f -printf "%M %TY-%Tm-%Td %TH:%TM:%TS %p\n" | sort -k2,3

FreeBSD などは find に -printf オプションがないため、ls の --full-time に頼るのがよいだろう。
% find . -type f | xargs ls --full-time '%Y%m%d%H%M%S'|sort -k6,7

find と xargs の組み合わせ
ソースの中から文字列「hogehoge」を検索するには下記のようにすればよいが、これでは *.c のファイルの数だけ grep コマンドが実行され、時間がかかる。
% find . -name \*.c -exec grep hogehoge {} \;

そういう場合は下記のように xargs コマンドを使うとよい。
% find . -name \*.c -print | xargs grep hogehoge

ファイル名に空白などが含まれる場合は -print 0 と xargs -0 を組み合わせる。
% find . -name \*.c -print0 | xargs -0 grep hogehoge /dev/null
これは Linux・FreeBSD 等では使えるが、Solaris 等の find コマンドでは -print0 オプションは実装されていないと思われる。

また、-exec {} + を使っても同じ効果がある。
% find . -name \*.c -exec grep hogeehoge {} +

find の -or オプションに括弧が必要な理由
下記はファイル名が abc か def のファイル・ディレクトリを検索する。
% find . -name abc -or -name def
しかしながら、
% find . -name abc -or -name def -print
のように -print などのアクションを付けると def は表示されるが、abc は表示されないので、
% find . \( -name abc -or -name def \) -print
と -or 部分を括弧で書こうようにすればよい、の理由について詳しく説明しよう。

まず、
% find . -name abc -or -name def -print

% find . -name abc -or -name def -and -print
と解釈される (条件を単に並べたものは -and で結んだのと同じであるため)。さらに結合順序は OR より AND が優先であるため、
% find . -name abc -or \( -name def -and -print \)
となる。よって、abc にマッチした場合は -print されないが、def にマッチした場合は -print されるのである。

一方で、なぜ
% find . -name abc -or -name def
の場合は表示されるのか疑問に思う人もいるかもしれない。find は -print・-ls・-exec などのアクション指定がない場合は自動的に -print を追加するので、それならば
% find . -name abc -or -name def -print
と同じではないか、と。実際は -print を追加するときに与えられた条件全体を括弧で囲った上で、末尾に -print を追加するのため、
% find . \( -name abc -or -name def \) -print
となるので、正しく動くのである。

注意点: csh・tcsh における -exec {} のエスケープ
csh・tcsh における -exec・-ok の注意点について。

下記は *.txt を *.txt.bak にリネームする例であるが、sh・bash ではうまくいくものの、csh・tcsh ではリネーム先ファイル名がすべて ".bak" になってしまう。
% find .-name \*.txt -exec mv {} {}.bak \;
これは find コマンドに関係なくシェルの違いであり、sh・bash では
$ echo {} {}.bak
{} {}.bak
となるのに対し、csh・tcsh では
% echo {} {}.bak
{} bak
となるためである。

下記のようにエスケープすると意図通りに動く。
% find .-name \*.txt -exec mv {} \{}.bak \;
下記のように {} の前にはエスケープを常に付けてもよい。もちろん sh・bash でも動く。
% find .-name \*.txt -exec mv \{\} \{\}.bak \;

関連コマンド
locate コマンドの方が高速にファイルを検索できる。locate コマンドが使えるなら、まずそちらを使うべし。

DOS・Windows の tree コマンドのような出力が欲しければ、tree コマンドを使うとよい。
% tree /usr
/usr/
|-- X11R6
| |-- bin
| | |-- ccmakedep
| | |-- (略)
| | `-- xmkmf
| |-- etc
| | |-- fonts
>> Linuxオンラインマニュアル(man) Linux find(1)
>> FreeBSDオンラインマニュアル(man) FreeBSD find(1)
>> Solaris10オンラインマニュアル(man) Solaris10 find(1)