Linuxのfindとは?ファイルやディレクトリを検索する場合に役立つfindコマンドを解説
Linux環境にてファイルやディレクトリを検索する場合には「find」コマンドを利用します。ファイル名は分かっていても「どこに格納されているのか分からない場合」や、「ある条件にマッチしたファイルのみを標準出力したい場合」など、利用される目的は様々ですが、本コンテンツでは一般的によく使われるfindコマンドをご紹介します。
目次
1.findコマンドとは
その名の通り「探す(検索)」コマンドです。対象となるのはファイルやディレクトリとなりますが、オプションによって柔軟な検索が行えますし、シェルスクリプトへ組み込む事で、安全かつ正確な処理を実現する事も可能です。
1-1.コマンドの使い方
findコマンドの基本的な使い方は、
となります。※△はスペースです。
検索対象ディレクトリの指定は「絶対パス」「相対パス」のいずれでも可能ですが、参照権限のないディレクトリを指定してしまうと、「Permission denied」として検索出来ませんのでご注意ください。※本コンテンツでは、権限(パーミッション)の説明は割愛させて頂きます。
1-2.よく使われるオプション一覧
Findコマンドには多くのオプションがありますが、一般的によく使われると思われるオプションをご紹介します。
オプション | 意味 |
-amin | 任意の分数にアクセスされたファイルやディレクトリを検索する。 |
-and | 複数の条件を使って、すべての条件に当てはまるファイルやディレクトリを検索する。 |
-anewer | 任意のファイルの更新日時よりも後にアクセスしたファイルやディレクトリを検索する。 |
-atime | 任意の日数にアクセスされたファイルやディレクトリを検索する。 |
-empty | ファイル容量が0のファイルやディレクトリを対象とし検索する。 |
-exec | 検索結果に対してコマンドを実行する。 |
-mmin | 任意の分数に更新されたファイルやディレクトリを検索する。 |
-mtime | 任意の日数に更新されたファイルやディレクトリを検索する。 |
-name | ワイルドカードを使用して、ファイルやディレクトリ名の一部のみ指定した検索ができる。 |
-newer | 任意のファイルの更新日時よりも後に変更したファイルやディレクトリを検索する。 |
-not | 条件に当てはまらないファイルやディレクトリを検索する。 |
-or | 複数の条件を使って、いずれかの条件に当てはまるファイルやディレクトリを検索する。 |
-perm | パーミッションで検索する。 |
-size | ファイル容量を指定し検索する。 |
-type d | ディレクトリを対象とし検索する。 |
-type f | ファイルのみを対象とし検索する。 |
表1.2.findコマンドのオプション一覧
2.コマンドの使用例
では実際にfindコマンドの使い方をご説明します。
2-1.ファイル名を指定して検索する
ファイル名「findtest1.txt」を検索する際、格納ディレクトリが「/home/engineer-club/findtest配下」だと分かっていれば、次のようなコマンドで検索が可能です。
/home/engineer-club/find-test/findtest1.txt
[engineer-club@test]$
上記のコマンドは、
- /home/engineer-club/find-testというディレクトリ配下にある
- findtest1.txtを検索(find)する
と言う命令文になります。
例えば、ファイルの格納場所が分からない場合、/(ルート)から検索する事も出来ます。
find: ‘/proc/tty/driver’: Permission denied
~中略~
find: ‘/home/postgres’: Permission denied
/home/engineer-club/find-test/findtest1.txt
[engineer-club@test]$
この様に「Permission denied(権限がありません)」のメッセージが表示されますが、参照可能なディレクトリに存在するファイルであれば検索が可能です。
2-2.ディレクトリ名を表示する
指定したディレクトリ配下にあるディレクトリを表示したい場合には、オプション「-type△d」を指定します。
total 2740
drwxrwxr-x. 2 engineer-club engineer-club 26 Apr 10 20:42 deltest
-rw-rw-r–. 1 engineer-club engineer-club 1998018 Apr 10 19:45 findtest1.txt
-rw-rw-r–. 1 engineer-club engineer-club 9018 Apr 10 19:21 findtest2.txt
-rw-r–r–. 2 engineer-club engineer-club 792434 Apr 3 17:13 findtest4.txt
drwxrwxr-x. 2 engineer-club engineer-club 66 Apr 10 20:57 tartes
[engineer-club@test]$find . -type d
.
./deltest
./tartest
[engineer-club@test]$
実行した結果、カレントディレクトリ(.)内のディレクトリのみ表示されます。
尚、ディレクトリの詳細を表示する際には「-ls」オプションを利用します。
201405 0 drwxrwxr-x 4 engineer-club engineer-club 99 Apr 10 20:49 .
8415728 0 drwxrwxr-x 2 engineer-club engineer-club 26 Apr 10 20:42 ./deltest
12589924 0 drwxrwxr-x 2 engineer-club engineer-club 66 Apr 10 20:57 ./tartest
[engineer-club@test]$
2-3.指定したサイズ以上/以下のファイルを検索する
ディスク使用率が逼迫しているので、一定サイズ以上のファイルを検索する時や、逆に一定サイズ以下(若しくは0バイトの不要ファイル)を検索する時には、次のコマンドを利用します。
①サイズが0バイトのファイル
0バイトのファイルを検索する際には、オプション「-empty」を用います。
total 1964
-rw-rw-r–. 1 engineer-club engineer-club 1998018 Apr 10 19:45 findtest1.txt
-rw-rw-r–. 1 engineer-club engineer-club 9018 Apr 10 19:21 findtest2.txt
-rw-rw-r–. 1 engineer-club engineer-club 0 Apr 10 19:13 findtest3.txt
[engineer-club@ test]$ find ./ -empty
./findtest3.txt
[engineer-club@ test]$
実行した結果、0キロバイトのファイルのみ検索されます。
②サイズが1キロバイト以下のファイル
ファイルサイズが1キロバイト以下のファイルを検索する際には、「-size」オプションを利用します。「-size」オプションは、バイトを「c」、キロバイトを「k」、メガバイトを「M」、ギガバイトを「G」で表す事ができ、例えば1キロバイト以上は「+1k」、逆に1キロバイト以下は「-1k」と指定します。
total 1964
-rw-rw-r–. 1 engineer-club engineer-club 1998018 Apr 10 19:45 findtest1.txt
-rw-rw-r–. 1 engineer-club engineer-club 9018 Apr 10 19:21 findtest2.txt
-rw-rw-r–. 1 engineer-club engineer-club 0 Apr 10 19:13 findtest3.txt
[engineer-club@ test]$ find ./ -size -1k
/home/engineer-club/find-test/findtest3.txt
[engineer-club@ test]$
実行した結果、1キロバイト以上のファイルのみ検索されます。
③サイズが1メガバイト以下のファイル
ファイルサイズが1メガバイト以上のファイルを検索する際にも同様に「-size」オプションを利用します。
total 1964
-rw-rw-r–. 1 engineer-club engineer-club 1998018 Apr 10 19:45 findtest1.txt
-rw-rw-r–. 1 engineer-club engineer-club 9018 Apr 10 19:21 findtest2.txt
-rw-rw-r–. 1 engineer-club engineer-club 0 Apr 10 19:13 findtest3.txt
[engineer-club@test]$find ./ -size +1M
./findtest1.txt
[engineer-club@test]$
実行した結果、1メガバイト以上のファイルのみ検索されます。
2-4.指定した日(以前・以降)に更新されたファイルを検索する
何らかの理由によりファイルが更新された場合、どのファイルが更新されたのか確認する際などにもfindコマンドは利用されます。例えば、誤ってファイル更新バッチなどを実行してしまい、処理を中断したなどの場合、更新されたファイルを検索してバックアップから戻す…と言った場合「-mtime」オプションを利用します。
①今日更新されたファイルを検索する
「-mtime」オプションは日単位で検索する事が可能なオプションであり、今日の更新であれば「0」、昨日の更新であれば「1」と、「何日前に更新されたのか」を指定できます。
Wed Apr 10 20:23:29 JST 2019
[engineer-club@test]$ls -l
total 2740
-rw-rw-r–. 1 engineer-club engineer-club 1998018 Apr 10 19:45 findtest1.txt
-rw-rw-r–. 1 engineer-club engineer-club 9018 Apr 10 19:21 findtest2.txt
-rw-rw-r–. 1 engineer-club engineer-club 0 Apr 10 19:13 findtest3.txt
-rw-r–r–. 1 engineer-club engineer-club 792434 Apr 3 17:13 findtest4.txt
[engineer-club@test]$find ./ -mtime 0
./findtest3.txt
./findtest2.txt
./findtest1.txt
[engineer-club@test]$
実行した結果、4/10に更新されたファイルのみが検索されます。
②n日以内に更新されたファイルを検索する
例えば、5日以内に更新されたファイルを検索する場合には「-mtime」オプションで「-5」を指定します。
Wed Apr 10 20:27:42 JST 2019
[engineer-club@test]$ls -l
total 2740
-rw-rw-r–. 1 engineer-club engineer-club 1998018 Apr 10 19:45 findtest1.txt
-rw-rw-r–. 1 engineer-club engineer-club 9018 Apr 10 19:21 findtest2.txt
-rw-rw-r–. 1 engineer-club engineer-club 0 Apr 10 19:13 findtest3.txt
-rw-r–r–. 1 engineer-club engineer-club 792434 Apr 3 17:13 findtest4.txt
[engineer-club@test]$find ./ -mtime -5
./findtest3.txt
./findtest2.txt
./findtest1.txt
[engineer-club@test]$
実行した結果、5日以内に更新されたファイルのみ検索されます。
③n日以前に更新されたファイルを検索する
上記②とは逆に、5日以前に更新されたファイルを検索する場合には、「+5」を指定します。
Wed Apr 10 20:30:23 JST 2019
[engineer-club@test]$ls -l
total 2740
-rw-rw-r–. 1 engineer-club engineer-club 1998018 Apr 10 19:45 findtest1.txt
-rw-rw-r–. 1 engineer-club engineer-club 9018 Apr 10 19:21 findtest2.txt
-rw-rw-r–. 1 engineer-club engineer-club 0 Apr 10 19:13 findtest3.txt
-rw-r–r–. 1 engineer-club engineer-club 792434 Apr 3 17:13 findtest4.txt
[engineer-club@test]$find ./ -mtime +5
./findtest4.txt
[engineer-club@test]$
実行した結果、5日以前に更新されたファイルのみ検索されます。
※本来であれば上記サンプルの結果には「./」と言うのが表示されますが、混乱を避けるため削除しております。
3.コマンドのサンプル
findコマンドを用いたサンプルをいくつかご紹介します。
3-1.検索結果のファイルを削除する
①「-delete」オプションによって削除する
total 4
-rw-rw-r–. 1 engineer-club engineer-club 0 Apr 11 22:22 deltest1.txt
-rw-rw-r–. 1 engineer-club engineer-club 0 Apr 11 22:22 deltest2.txt
-rw-rw-r–. 1 engineer-club engineer-club 14 Apr 10 20:36 deltest3.txt
[engineer-club@test]$find -empty -delete
[engineer-club@test]$ls -l
total 4
-rw-rw-r–. 1 engineer-club engineer-club 14 Apr 10 20:36 deltest3.txt
[engineer-club@test]$
実行の結果、0バイトのファイルのみが削除されました。単に削除するのであればこの方法が簡単です。
②「-exec」オプションによってrmコマンドを実行する
total 4
-rw-rw-r–. 1 engineer-club engineer-club 0 Apr 11 21:11 deltest1.txt
-rw-rw-r–. 1 engineer-club engineer-club 0 Apr 11 21:11 deltest2.txt
-rw-rw-r–. 1 engineer-club engineer-club 14 Apr 10 20:36 deltest3.txt
[engineer-club@test]$find -empty -exec rm {} \;
[engineer-club@test]$ls -l
total 4
-rw-rw-r–. 1 engineer-club engineer-club 14 Apr 10 20:36 deltest3.txt
[engineer-club@test]$
実行の結果、検索された0バイトのファイルは「{}」に格納され、「-exec」オプションによってrmコマンドが実行(削除)されました。ここでポイントとなるのは、「\;」です。これはコマンドの終わりを示しており、省略してしまうとコマンドが不完全なものとなってしまいエラーになります。こちらは、検索した結果をコマンドへ引き渡す際に用いられます。
③インタラクティブに削除対象を確認する
また、上記のコマンドでは削除可能なファイルである場合、確認せずに削除されてしまいます。セキュリティ的にインタラクティブな処理を行う場合には、rmコマンドの「-i」オプションを指定すると良いでしょう。
total 4
-rw-rw-r–. 1 engineer-club engineer-club 0 Apr 11 21:44 deltest1.txt
-rw-rw-r–. 1 engineer-club engineer-club 0 Apr 11 21:44 deltest2.txt
-rw-rw-r–. 1 engineer-club engineer-club 14 Apr 10 20:36 deltest3.txt
[engineer-club@test]$find -empty -exec rm -i {} \;
rm: remove regular empty file ‘./deltest1.txt’? y
rm: remove regular empty file ‘./deltest2.txt’? y
[engineer-club@test]$ls -l
total 4
-rw-rw-r–. 1 engineer-club engineer-club 14 Apr 10 20:36 deltest3.txt
[engineer-club@test]$
実行の結果、rmコマンドの「-i」オプションにより「remove regular empty file ‘./deltest1.txt’?」と削除しても良いか確認してくれます。(y若しくはyesを入力すれば実行、nまたはnoを入力すればキャンセルとなります)
④削除リストへ出力した後に削除する
さらに、削除対象のファイルをリストへ出力したり、単一のファイルへ結合してから削除するなど、複雑な処理を行う場合には、for文などのループ処理に組み込むことが出来ます。
total 4
-rw-rw-r–. 1 engineer-club engineer-club 0 Apr 11 21:55 deltest1.txt
-rw-rw-r–. 1 engineer-club engineer-club 0 Apr 11 21:55 deltest2.txt
-rw-rw-r–. 1 engineer-club engineer-club 14 Apr 10 20:36 deltest3.txt
[engineer-club@test]$for list in `find -empty`
> do
> echo $list >> delete-file.txt
> rm $list
> done
[engineer-club@test]$ ls -l
total 8
-rw-rw-r–. 1 engineer-club engineer-club 30 Apr 11 21:56 delete-file.txt
-rw-rw-r–. 1 engineer-club engineer-club 14 Apr 10 20:36 deltest3.txt
[engineer-club@test]$cat delete-file.txt
./deltest1.txt
./deltest2.txt
[engineer-club@test]$
実行の結果、$listには0バイトのファイルがセットされ、do~doneの処理がループされます。つまり、1回目のループでは「deltest1.txt」がセットされ、echoコマンドによってdelete-file.txtへ出力され、その後rmコマンドによって削除されます。次いで2回目のループでは「deltest2.txt」がセットされ、同様にdelete-file.txtへ出力された後に削除されます。そして、$listには上記2つのファイル名しか格納されていないのでforループは終了し、同一ディレクトリには作成されたdelete-file.txtおよび、0バイトではないdeltest3.txtのみが残る結果となります。
<一口メモ>
forコマンドの基本形は、「for [変数名] in [リスト];do [処理内容];done;」となり、リストの1行目を変数へ格納し、do~doneの処理をリストの最終行まで実行するものです。指定ファイルの中身をリストとする事も出来ますが、バッククォーテーション(‘)で括る事で、コマンドによるリスト作成も可能です。
※バッククォーテーションは一般的な日本語キーボードの「Shift+@」です。
3-2.5日以前に更新されたファイルをアーカイブ化してzip圧縮する
total 776
-rw-rw-r–. 1 engineer-club engineer-club 0 Apr 10 20:49 tartest1.txt
-rw-rw-r–. 1 engineer-club engineer-club 0 Apr 10 20:49 tartest2.txt
-rw-r–r–. 2 engineer-club engineer-club 792434 Apr 3 17:13 tartest3.txt
[engineer-club@test]$for i in `find ~/ -mtime +5|grep tartest`
> do
> tar zcvf $i.zip $i
> done
/home/engineer-club/find-test/tartest/tartest3.txt
[engineer-club@test]$ ls -l
total 856
-rw-rw-r–. 1 engineer-club engineer-club 0 Apr 10 20:49 tartest1.txt
-rw-rw-r–. 1 engineer-club engineer-club 0 Apr 10 20:49 tartest2.txt
-rw-r–r–. 2 engineer-club engineer-club 792434 Apr 3 17:13 tartest3.txt
-rw-rw-r–. 1 engineer-club engineer-club 81677 Apr 10 20:56 tartest3.txt.zip
[engineer-club@test]$
実行の結果、リストiには5日以前に更新されたファイル名がセットされ、tarコマンドによってアーカイブ化および、オプション「z」によってzip形式の圧縮が行われています。尚、for分のtarコマンド以降に、rm $iを加えることで、圧縮元となるファイルを削除する事も出来るので、シェルスクリプトとしてcronへ登録する事で、ログファイルなどのローテーションに用いられます。
4.最後に
文字列を検索するgrepコマンドに対し、ファイルやディレクトリを検索するfindコマンドをご紹介しました。どちらもシェルスクリプトに組み込まれる事が多いコマンドでもあり、かつ、Liux環境で何かを調べると言った場合にも重宝するコマンドですので、色々と使いこなしてみて下さい。
コメント