findコマンドの基本的な使い方

2021/03/12更新

目次

基本

findコマンドの構文

findコマンドは、最初の引数に検索対象のパス、その後ろに検索条件などを与えて実行する。検索対象のパスは複数指定することもできる。

# カレントディレクトリ以下を無条件で検索(=全てのファイルが列挙される)
find .

# /var/tmpと/var/log以下の通常ファイルを検索
find /var/tmp /var/log -type f

検索条件

ファイルの種類による検索

-typeでファイルの種類を指定できる。fは通常ファイル、dはディレクトリ、lはシンボリックリンクを検索する。

# 通常ファイルを検索
find . -type f

名前による検索

-nameでファイル名を指定できる。*(0文字以上)などのワイルドカードが使用できる。

# 拡張子が「.html」のファイルを検索
find . -name '*.html'

大文字小文字を無視するには-inameを使う。

パスによる検索

-pathを使うとパス全体を検索条件にできる。

# パス中に/hoge/を含むファイルを検索
find . -path '*/hoge/*'

大文字小文字を無視するには-ipathを使う。

ユーザー/グループによる検索

-userでユーザー、-groupでグループを検索条件にできる。名前でもIDでもどちらでも指定できる。

# hogeuserのファイルを検索
find . -user hogeuser

更新日時による検索

現在からの時間差で検索する場合は、-mtimeを使う。-mtimeの後には日数Nを-NN+Nのいずれかで指定する。例えば、現在時刻を12/31 12:34とした場合、それぞれ以下の範囲がヒットする。また、-mtimeの前に-daystartを付けると、範囲の境界が日付の境界となる。なお、Nには小数も指定できる。

# 24時間以内に更新されたファイルを検索
find . -mtime -1

# 今日更新されたファイルを検索
find . -daystart -mtime -1

12/27

12/28

12/29

12/30

12/31

00

12

12

23

00

12

12

23

00

12

12

23

00

12

12

23

00

12

00

34

35

59

00

34

35

59

00

34

35

59

00

34

35

59

00

34

-daystartなし

-mtime +1

-mtime 1

-mtime -1

-mtime +2

-mtime 2

-mtime -2

-mtime +3

-mtime 3

-mtime -3

-daystartあり

-mtime +1

-mtime -1

-mtime +2

-mtime -2

-mtime +3

-mtime -3

  • ※:筆者が複数の環境で確認した限り、-daystartを付けたときの-mtime Nはどうも挙動がおかしく、範囲の境界が1秒ずれる(「00:00:00~23:59:59」ではなくなぜか「00:00:01~24:00:00」がヒットする)ようである。この※の範囲を検索したい場合は、例えば-daystart -mtime +1 -mtime -3のように2つの範囲のAND条件で検索する方が無難である。

-mminを使うと現在時刻からの時間差を分単位で指定できる。こちらは-mtimeと異なり、-N+Nの範囲が連続しており、符号なしのN-N+(N-1)の重なる範囲となる。

# 5分以内に更新されたファイルを検索
find . -mmin -5

# 5分以上前に更新されたファイルを検索
find . -mmin +5

-mtime-mminの1文字目のmは「更新日時」で検索することを表す。作成日時で検索するには-ctime-cmin、アクセス日時で検索するには-atime-aminを使う。

-newerを使うと、指定したファイルよりも更新日時が新しいファイルを検索できる。また、-newermtを使うと、指定した日時より新しいファイルを検索できる(-newermtmは「更新日時」、tは「日時として解釈する」という意味で、他にも機能がある)。

# 更新日時がhoge.txtよりも新しいファイルを検索
find . -newer hoge.txt

# 更新日時が「2020/12/31 23:59:59」よりも新しいファイルを検索
find . -newermt '2020-12-31 23:59:59'

ファイルサイズによる検索

-sizeでファイルサイズを検索条件にできる。数値だけを指定するとバイトではなく「512バイトのブロック単位」と見なされてしまうので注意が必要である。+をつけると「より大きい」、-をつけると「より小さい」を表す。

# 1024バイトのファイルを検索
find . -size 1024c

# 1024バイトより小さい(1023バイト以下)のファイルを検索
find . -size -1024c

# 1024バイトより大きい(1025バイト以上)のファイルを検索
find . -size +1024c

# 1KiB(1024バイト)より大きいファイルを検索
find . -size +1k

# 1MiB(1048576バイト)より大きいファイルを検索
find . -size +1M

# 1GiB(1073741824バイト)より大きいファイルを検索
find . -size +1G

-emptyは空であるファイルまたはディレクトリを検索できる。

パーミッションによる検索

-permでパーミッションを検索条件にできる。

# パーミッションが644のファイルを検索
find . -perm 644

-を付けると、指定したビットが全て立っているものが検索対象となる。

# 全てに実行権限が付いているファイルを検索
find . -perm -111

# ユーザーに読み取り、書き込み、実行権限が全て付いているファイルを検索
find . -perm -700

+を付けると、指定したビットのいずれかが立っているものが検索対象となる。

# グループまたはその他のいずれかに書き込み権限が付いているファイルを検索
find . -perm +022

# その他に読み取り、書き込み、実行権限のいずれかが付いているファイルを検索
find . -perm +007

検索条件の組合せ

AND条件

複数の検索条件をただ並べていくと通常はAND条件となる。

# 通常ファイル、かつ、拡張子が.htmlのファイルを検索
find . -type f -name '*.html'

OR条件

-oまたは-orを条件の間に挟むとOR条件となる。

# 拡張子が.jpgまたは.pngのファイルを検索
find . -name '*.jpg' -o -name '*.png'

ANDやORの優先順位を明確にするためにカッコ\( ~ \)が使える。

# 通常ファイル、かつ、拡張子が.jpgまたは.pngのファイルを検索
find . -type f \( -name '*.jpg' -o -name '*.png' \)

NOT条件

-notまたは!を条件の前に置くと、条件の否定となる。

# パスに/hoge/を含まないファイルを検索
find . -not -path '*/hoge/*'

検索範囲

検索する深さ

-mindepth-maxdepthで検索するディレクトリの深さを指定できる。0は指定したパス自身、1は指定したパスの直下、2はさらにその下…となる。

# 指定したディレクトリ自身を除外して検索
find . -mindepth 1

# 指定したディレクトリ直下のみを検索
find . -maxdepth 1

特定ディレクトリの除外

node_modules.gitなどのディレクトリを除外したい場合、-pruneというオプションを使う。

# node_modulesディレクトリ以下は検索せず、それ以外の通常ファイルを検索
find . -name 'node_modules' -prune -o -type f -print

-pruneの使い方は初見では分かりにくい。まず、-oの前半で除外すべきディレクトリを表す条件(上記例では-name 'node_modules')と-pruneオプションを記述する。-pruneは「ヒットしたディレクトリを辿らない」という意味で、それ自体は条件として真を返す。そのため、除外したいディレクトリがヒットした場合は-o以降の条件が評価されない。一方、除外したいディレクトリ以外の場合は、-o以前の条件が偽となるため、-o以降で指定した条件(上記例では-type f)が評価され、通常の検索が行なわれる。

注意点として、-pruneを使う場合、最後に-print-printfを付けて出力を明示する必要がある。そうしないと、除外したいディレクトリ自身も自動的に出力されてしまう。-print-printfを付けると-o以降の条件で真となったものだけが出力されるようになり、除外したいディレクトリ自身が出力されなくなる。

特定ディレクトリを除外するには、-not -path '*/node_modules/*'などとする方法もあるが、-pruneを使う方が検索対象そのものから外されるので、効率が良い。

検索結果

xargsへの出力

-print0を指定すると、検索結果のパスをNULL文字\x00で区切って出力する。これとxargsコマンドの-0を組み合わせると、名前にスペースを含むファイルなどを正しく取り扱うことができる。

find . -type f -print0 | xargs -0 cat

詳細情報の出力

-lsを指定すると、lsコマンドのように、パスとともにサイズや更新日時も出力する。実際にls -dilsで出力されるのと同じ形式となる。

出力のフォーマット

-printfで出力のフォーマットを指定できる。

# ファイル名と最終更新日を出力
find . -type f -printf "%f %TY/%Tm/%Td\n"

書式文字列として以下のようなものが使用できる。%自体は%%と書く。改行\nなども自分で指定する必要がある。

書式

意味

%p

ファイル名(検索対象に指定したディレクトリから始まるパスを含む)

%f

ファイル名のみ

%P

ファイル名(検索対象に指定したディレクトリからの相対パス)

%h

ディレクトリパス(%pから%fを除いた部分)

%H

ディレクトリパス(%pから%Pを除いた部分)

%y

ファイルの種類

%u

ユーザー名

%U

ユーザーID

%g

グループ名

%G

グループID

%s

ファイルサイズ(バイト)

%l

シンボリックリンクのリンク先

%m

パーミッション(八進数表記)

%M

パーミッション(記号表記)

%t

最終更新日時

※以下のようにして個別の値も得られる。

  • %T@:Unix Time(小数あり)

  • %TY:年(4桁)

  • %Tm:月(01~12)

  • %Td:日(01~31)

  • %TH:時(00~23)

  • %TM:分(00~59)

  • %TS:秒(小数あり)

  • %TT:時刻(%TH:%TM:%TSに同じ)

  • %Tz:タイムゾーン

検索結果を使ってのコマンド実行

-execを使うと、検索して見つかったファイルを使ってコマンド実行することができる。コマンドを指定する際は、ファイル名を入れる場所に{}を置き、さらに最後に\;を置く。

以下は、カレントディレクトリ以下の拡張子が.tmpのファイルをrmコマンドに渡して削除する例である。

find . -name '*.tmp' -exec rm {} \;

-execと同様のオプションに-okがある。-okを使うと、実行前に1ファイルずつ確認のプロンプトを出してくれる。

外部リンク