find は、指定したディレクトリの下にあるファイルやディレクトリを、名前や種類、サイズ、更新日時などの条件で探すコマンドです。この記事では、よく使うオプションを実際に実行し、結果を確かめながら使い方を整理します。
- find の基本の書き方(検索対象のパスと検索条件)
- 名前・種類・サイズ・更新日数で探すオプション(-name、-type、-size、-mtime)
- 条件の組み合わせ(AND、-or、-not)と括弧のエスケープ
- 見つかったファイルへのアクション(-print、-ls、-delete)
find の基本の書き方
find は、検索対象のパスのあとに検索条件を書きます。
find <検索対象のパス> <検索条件>
たとえば、/home/hirotano ディレクトリの下から、名前が data1 のファイルを探すには次のようにします。
hirotano@linux-1:~$ find /home/hirotano/ -name data1
/home/hirotano/data1
検索対象のパスの下にあるサブディレクトリも、すべて検索します。検索条件には、ファイルの名前や種類、サイズ、更新日時など、さまざまなオプションを指定できます。
この記事では、ホームディレクトリ(カレントディレクトリ)にある次のファイルとディレクトリを検索の対象にします。
hirotano@linux-1:~$ ls -la 合計 1034312 drwxr-xr-x 8 hirotano hirotano 4096 12月 25 04:33 . drwxr-xr-x 3 root root 4096 7月 31 06:45 .. -rw------- 1 hirotano hirotano 7189 12月 25 05:29 .bash_history -rw-r--r-- 1 hirotano hirotano 220 2月 25 2020 .bash_logout -rw-r--r-- 1 hirotano hirotano 3771 2月 25 2020 .bashrc drwx------ 2 hirotano hirotano 4096 7月 31 06:49 .cache drwx------ 3 hirotano hirotano 4096 12月 11 02:15 .config -rw------- 1 hirotano hirotano 69 12月 24 14:31 .lesshst drwxrwxr-x 3 hirotano hirotano 4096 12月 18 08:19 .local -rw-r--r-- 1 hirotano hirotano 807 2月 25 2020 .profile drwx------ 2 hirotano hirotano 4096 7月 31 08:42 .ssh -rw-r--r-- 1 hirotano hirotano 0 7月 31 06:49 .sudo_as_admin_successful -rw------- 1 hirotano hirotano 8860 12月 11 11:14 .viminfo -rw-rw-r-- 1 hirotano hirotano 0 12月 19 12:00 1-music -rw-rw-r-- 1 hirotano hirotano 0 12月 24 06:17 11-music -rw-rw-r-- 1 hirotano hirotano 0 12月 24 06:17 2-music -rw-rw-r-- 1 hirotano hirotano 0 12月 24 06:05 Backup111 -rw-rw-r-- 1 hirotano hirotano 0 12月 24 06:05 Backup222 -rw-rw-r-- 1 hirotano hirotano 0 12月 24 06:05 Backup333 -rw-rw-r-- 1 hirotano hirotano 0 12月 24 06:06 IMAGE -rw-rw-r-- 1 hirotano hirotano 0 12月 24 06:05 IMAGE1 -rw-rw-r-- 1 hirotano hirotano 0 12月 24 06:06 IMAGE12 -rw-rw-r-- 1 hirotano hirotano 10485760 12月 25 01:42 data1 -rw-rw-r-- 1 hirotano hirotano 1048576000 12月 25 03:51 data11 -rw-rw-r-- 1 hirotano hirotano 0 12月 24 06:04 data111 drwxrwxr-x 2 hirotano hirotano 4096 12月 24 08:50 dir1 drwxrwxr-x 2 hirotano hirotano 4096 12月 24 06:03 dir11 -rw-rw-r-- 1 hirotano hirotano 0 12月 24 06:04 file1 -rw-rw-r-- 1 hirotano hirotano 0 12月 24 06:04 file2.txt
名前で検索(-name)
上の例のように、-name のあとに探したい名前を指定します。-name が比べるのは、パスからディレクトリの部分を除いたファイル名です。大文字と小文字を区別しないで探したいときは -iname を使います。
「ある文字列で始まる」のような条件は、ワイルドカード(* や ?)で指定します。ワイルドカードの意味は、次の記事を参考にしてください。
ワイルドカードは引用符で囲む
たとえば、カレントディレクトリ(.)の下から、名前が d で始まるものを探す場合は次のようにします。ワイルドカードを使うときは、パターンを引用符(ここではシングルクォート)で囲みます。
hirotano@linux-1:~$ find . -name 'd*'
./dir11
./data11
./data111
./dir1
./data1
引用符がないと、find が動く前に bash がパス名展開をします。カレントディレクトリに d で始まるファイルがあると、d* は data1 data11 data111 dir1 dir11 に置き換わり、find は -name のあとに名前が並んだ形で実行されるので、エラーになります。find には、展開する前の d* のまま渡す必要があります。
引用符なしでも、たまたま動いてしまうことがあります。カレントディレクトリに一致するファイルが1つだけならその名前に置き換わってエラーにならず、一致するファイルがなければ d* がそのまま渡ります。どちらも意図した検索になるとは限らないので、ワイルドカードはいつも引用符で囲みます。
* の前にバックスラッシュを入れて、パス名展開をエスケープすることもできます。
hirotano@linux-1:~$ find . -name d\*
./dir11
./data11
./data111
./dir1
./data1
ファイルタイプで検索(-type)
ファイルかディレクトリかを条件にするには、-type を使います。通常のファイルは f、ディレクトリは d、シンボリックリンクは l を指定します。
次は、カレントディレクトリの下のディレクトリを探した例です。カレントディレクトリ自身(.)もディレクトリなので、結果に含まれます。
hirotano@linux-1:~$ find . -type d
.
./.local
./.local/share
./.local/share/nano
./dir11
./.ssh
./dir1
./.config
./.config/procps
./.cache
ファイルサイズで検索(-size)
ファイルのサイズを条件にするには、-size を使います。カレントディレクトリの下から 5M バイトを超えるファイルを探すには、-size のあとに +5M と指定します。
hirotano@linux-1:~$ find . -size +5M
./data11
./data1
数字の前の + は「より大きい」、- は「より小さい」を表し、どちらも付けなければ「ちょうど」を表します。単位は M(MiB)のほかに、c(バイト)、k(KiB、小文字)、G(GiB)が使えます。単位を省くと、512 バイトのブロック単位になります。
結果を見ると、10485760 バイト(10MiB)の data1 と、1048576000 バイト(1000MiB)の data11 が見つかっています。
サイズは指定した単位に切り上げてから比べます。そのため -size -1M は「1MiB 未満」ではなく、サイズ 0 のファイルにしか一致しません。小さいサイズを細かく指定したいときは、-size -1048576c のようにバイト(c)で指定します。
更新日数で検索(-mtime)
ファイルの中身が最後に更新されてからの日数を条件にするには、-mtime を使います。日数は 24 時間を1日として数え、端数は切り捨てます。
カレントディレクトリの下から、5日前に更新されたファイルを探すには、-mtime のあとに 5 を指定します。この 5 は、更新から 5×24 時間以上、6×24 時間未満のものを指します。
hirotano@linux-1:~$ find . -mtime 5
./1-music
5日前より新しいもの(5×24 時間たっていないもの)は -5、もっと古いものは +5 と指定します。+5 は、端数を切り捨てた日数が 5 より大きいもの、つまり 6×24 時間以上前に更新されたものです。
次は、5日前より新しいファイルを探した例です。
hirotano@linux-1:~$ find . -mtime -5
.
./.bash_history
./dir11
./2-music
./11-music
./IMAGE12
./Backup111
./data11
./.lesshst
./IMAGE1
./file2.txt
./data111
./dir1
./file1
./Backup333
./IMAGE
./data1
./Backup222
複数の条件を指定
検索条件は、いくつでも並べられます。並べた条件は AND(すべてを満たすもの)として扱われます。たとえば、5日前に更新され、かつ名前が music で終わるファイルを探すには次のようにします。
hirotano@linux-1:~$ find . -name '*music' -mtime 5
./1-music
OR と NOT
条件どうしの関係は、論理演算子で指定することもできます。OR は -or、AND は -and と書きます(-o、-a と書いても同じです)。
\( 検索条件1 \) -or \( 検索条件2 \)
たとえば、名前が data で始まるもの、または5日前に更新されたものを探すには次のようにします。
hirotano@linux-1:~$ find . \( -name 'data*' \) -or \( -mtime 5 \)
./data11
./1-music
./data111
./data1
括弧(( と ))は bash では特別な意味を持つ文字なので、バックスラッシュでエスケープします。また、括弧と条件の間にはスペースを入れます。
条件の前に -not を付けると、その条件を満たさないものを探せます。次は、名前が music で終わり、かつ5日前に更新されていないファイルを探した例です(最後の \) は次の行に表示されています)。
hirotano@linux-1:~$ find . \( -name '*music' \) -and \( -not -mtime 5
\)
./2-music
./11-music
括弧を使わない場合、-and は -or より先に評価されます。AND と OR を混ぜるときは、意図した順に評価されるよう括弧で囲みます。
アクション
find には、見つかったファイルに対して何かをする「アクション」のオプションがあります。アクションを指定しない場合は、見つかったものを表示する -print が実行されます。-print を付けて実行すると、付けない場合と同じ結果になります。
hirotano@linux-1:~$ find . -name 'd*' -print
./dir11
./data11
./data111
./dir1
./data1
-ls を付けると、ls -dils の形式で表示されます。更新日時やサイズ、パーミッションをまとめて確かめたいときに使います。
hirotano@linux-1:~$ find . -name 'd*' -ls
524312 4 drwxrwxr-x 2 hirotano hirotano 4096 12月 24 06:03 ./dir11
393253 1024004 -rw-rw-r-- 1 hirotano hirotano 1048576000 12月 25 03:51 ./data11
393254 0 -rw-rw-r-- 1 hirotano hirotano 0 12月 24 06:04 ./data111
524311 4 drwxrwxr-x 2 hirotano hirotano 4096 12月 24 08:50 ./dir1
393252 10240 -rw-rw-r-- 1 hirotano hirotano 10485760 12月 25 01:42 ./data1
| 列(data11 の行) | 意味 |
|---|---|
| 393253 | inode 番号 |
| 1024004 | 使っているブロック数(1KiB 単位) |
| -rw-rw-r– | ファイルの種類とパーミッション |
| 1 | ハードリンクの数 |
| hirotano hirotano | 所有者とグループ |
| 1048576000 | サイズ(バイト) |
| 12月 25 03:51 | 最終更新日時 |
| ./data11 | パス |
-delete を付けると、見つかったものを削除します。次の例では、d で始まるファイルと、空のディレクトリ dir1、dir11 が削除され、もう一度探しても何も見つかりません。
hirotano@linux-1:~$ find . -name 'd*' -delete
hirotano@linux-1:~$ find . -name 'd*'
hirotano@linux-1:~$
-deleteは確認なしで削除します。先に同じ条件で-print(またはアクションなし)を実行して、対象を確かめてから実行します。- find は、コマンドラインを左から順に式として評価します。
-deleteを条件より前に書くと、条件で絞り込む前にすべてを削除しようとするので、-deleteは必ず最後に書きます。 - ディレクトリは、空のときだけ削除できます。中身が残っているディレクトリの削除は失敗します。
まとめ
| 書き方 | 意味 |
|---|---|
| -name ‘d*’ | 名前が d で始まる(ワイルドカードは引用符で囲む) |
| -type f / d / l | 通常のファイル/ディレクトリ/シンボリックリンク |
| -size +5M | 5MiB より大きい(- はより小さい、符号なしはちょうど) |
| -mtime 5 | 5×24 時間以上、6×24 時間未満に更新 |
| -mtime -5 / +5 | 5×24 時間より新しい/6×24 時間以上前 |
| 条件1 条件2 | AND(-and、-a と同じ) |
| \( 条件1 \) -or \( 条件2 \) | OR。括弧はエスケープして前後にスペース |
| -not 条件 | 条件を満たさない |
| -print / -ls / -delete | 表示(省略時)/ls -dils 形式で表示/削除 |
コメント