UNIXの部屋 コマンド検索: find

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


検索 :
複数のキーワードを空白で区切ると AND 検索を行います。例:「ファイル 削除」


find ファイルを検索する。

基本的には
% find 検索開始ディレクトリ 検索条件 コマンド
という書式で使う。FreeBSD・Linux など一部の find では、
% find /usr
と、検索開始ディレクトリのみを指定すると、コマンドとして -print が指定されたものとして動作する。また、Linux の find では
% find
と検索開始ディレクトリの省略も可能。この場合カレントディレクトリが検索開始ディレクトリとみなされる。

注意
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 以下の全ファイルを表示

検索条件
-name file
検索するファイルを指定。ワイルドカードとして *・?・[・] を使用することが可能だが、その場合は "" などで囲むこと。ファイル名のみが検索対象であることに注意。カレントディレクトリ以下に
abc.txt
xxx/
xxx/abc.txt
abc/
abc/def.txt
というファイル・ディレクトリがあるとき、
% find . -name "*abc*"
とすると、abc.txt と abc/ と xxx/abc.txt はマッチするが、abc/def.txt はマッチしない。
-iname file
検索するファイル名を指定。大文字小文字を区別しない以外は -name と同じ。
-regex reg
パスを含むファイル名全体が正規表現 reg にマッチするものを検索する。-name と異なり、検索対象がパスも含むことに注意。また、「〜を含む」ではなく、「全体がマッチする」という条件であることにも注意。例えば
% find . -regex "abc"
は絶対にマッチしない。なぜなら、カレントディレクトリに abc というファイルがあった場合は「./abc」と出力されるが、これは -regex で指定した「abc」とマッチしないからである。この場合は
% find . -regex ".*abc.*"
としなければならない。
-iregex reg
大文字小文字を区別しない以外は、-regex と同じ。
-atime [+-]n
n日前にアクセスされたファイル。
-atime 4 4日前にアクセスされたファイル
-atime +4 5日以前にアクセスされたファイル
-atime -4 3日以内にアクセスされたファイル
-ctime [+-]n
n日前にファイルステータスが変更されたファイル
-ctime 4 ちょうど4日前にファイルステータスが変更されたファイル
-ctime +4 5日以前にファイルステータスが変更されたファイル
-ctime -4 3日以内にファイルステータスが変更されたファイル
-mtime [+-]n
n日前に修正されたファイル
-mtime 4 ちょうど4日前に修正されたファイル
-mtime +4 5日以前に修正されたファイル
-mtime -4 3日以内に修正されたファイル
-group グループ名
指定のグループに属するファイル
-inum inode 番号
指定の inode のファイルまたはディレクトリ。inode は ls -i で確認できる。inode はファイルシステムごとの通番のような番号なので、複数のファイルシステムにまたがった場合は同じ inode が存在する可能性があることに注意。

例えば、/・/usr・/home・/var という 4つのファイルシステムがマウントされている場合、
% find /usr -inum 100
であればファイルが 1つに特定できるが、
% find / -inum 100
とすると /・/usr・/home・/var それぞれの inode が 100 であるファイルが表示される可能性がある。
>> コマンド ls *
-newer file
ファイル file よりタイムスタンプが新しいファイル・ディレクトリを検索。タイムスタンプ比較用ファイルをあらかじめ作成し、touch コマンドを使ってタイムスタンプを変更し、そのファイルと比較するとよい。

逆に、「〜より古い」という条件で検索したい場合は、条件の否定を使う。
% find . ! -newer file -print
>> コマンド touch *
-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"
と同じである。

-type * ファイルの種類
b ブロックデバイス
c キャラクタデバイス
d ディレクトリ
f ファイル
l シンボリックリンク
p 名前付きパイプ
s ソケット (UNIX ドメインソケット)
D Door (Solaris のみ)
-size [+-]n[c]
ブロックサイズまたはファイルサイズで検索。「-size 100」だとブロックサイズとみなし、「-size 100c」などと末尾に c をつけるとファイルサイズとみなす。
% 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 で参照できる。
>> コマンド ls *
条件の結合・否定など
-a または -and
検索条件を AND で結ぶ。
% find . -name abc -and -type d
⇒ abc という名前のディレクトリを検索
ただし、複数の検索条件を並べて書けば AND として扱われるので、上記コマンドは
% find . -name abc -type d
と同じ。
-o または -or
検索条件を OR で結ぶ。
% find . -name abc -or -type d
⇒ abc という名前のファイル・ディレクトリか、あるいはディレクトリを検索
! または -not
他の条件の前に付けて、条件を否定する。-not は一部の find でしか使えない。
% find . ! -name \*.txt -print
⇒ 拡張子が .txt で *ない* ファイル・ディレクトリ
% find . -not -newer target.txt -print
⇒ target.txt とタイムスタンプが同じか、あるいは古いファイル・ディレクトリ
コマンド
-print 検索ファイルを表示
-ls 検索ファイルを詳しく (ls -l と同じように) 表示
より正確に言うと、行頭に inode と使用ブロックサイズが表示されるため、ls -lis と同じである。
-exec 検索ファイルを引数としてコマンドを実行
-ok -exec と同じだが、実行する際に確認を求める


% find / -name .cshrc -print
⇒ ルートディレクトリ以下の .cshrc を検索してフルパスを表示する
% find /usr/local -name file\* -ls
⇒ /usr/local 以下の file* を検索して詳細な情報を表示する
% find . -name \*~ -exec rm {} \;
⇒ カレントディレクトリ以下の *~ をリストアップして「rm 検索したファイル名」を実行する。{}の場所には検索したファイル名が入る。; はコマンドの終了を表すが、シェルに「;」を解釈させず、find へ「;」を渡すためにエスケープしてある。また、「{}」と「\」の間には必ずスペースを空けなくてはならない。
% find . -name \*~ -print -exec rm {} \;
⇒ コマンドは複数個指定できる。
% find . -name \*~ -exec ls {} \; -exec rm {} \;
⇒ (この例はあまり意味はないが) -exec を複数個指定してもよい。

他ユーザのディレクトリを検索する場合、読み込み権限のないディレクトリは permission denied と表示され、出力が見にくくなる。csh・tcsh なら
% (find / -name hoge\* -print >/dev/tty ) >& /dev/null
とすることで、標準エラー出力のみを捨てることができる。sh・bash なら
% find / -name fvwm\* -print 2>/dev/null
とすればよい。
>> 用語集 リダイレクト *

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

ソースの中から文字列「hogehoge」を検索するには
% find . -name \*.c -exec grep hogehoge {} \;
とすればよいが、これでは *.c のファイルの数だけ grep コマンドが実行され、時間がかかる。そういう場合は
% find . -name \*.c -print | xargs grep hogehoge
とすればよい。もっときっちりやるなら
% find . -name \*.c -print0 | xargs -0 grep hogehoge /dev/null
なのだが、詳しくはマニュアルを読んでくれい。
>> コマンド locate *   xargs *   tree *