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を-N
、N
、+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 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
を使うと、指定した日時より新しいファイルを検索できる(-newermt
のm
は「更新日時」、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
なども自分で指定する必要がある。
書式 | 意味 |
---|---|
| ファイル名(検索対象に指定したディレクトリから始まるパスを含む) |
| ファイル名のみ |
| ファイル名(検索対象に指定したディレクトリからの相対パス) |
| ディレクトリパス( |
| ディレクトリパス( |
| ファイルの種類 |
| ユーザー名 |
| ユーザーID |
| グループ名 |
| グループID |
| ファイルサイズ(バイト) |
| シンボリックリンクのリンク先 |
| パーミッション(八進数表記) |
| パーミッション(記号表記) |
| 最終更新日時 ※以下のようにして個別の値も得られる。
|
検索結果を使ってのコマンド実行
-exec
を使うと、検索して見つかったファイルを使ってコマンド実行することができる。コマンドを指定する際は、ファイル名を入れる場所に{}
を置き、さらに最後に\;
を置く。
以下は、カレントディレクトリ以下の拡張子が.tmpのファイルをrm
コマンドに渡して削除する例である。
find . -name '*.tmp' -exec rm {} \;
-exec
と同様のオプションに-ok
がある。-ok
を使うと、実行前に1ファイルずつ確認のプロンプトを出してくれる。