Tutorial

Linuxでファイルを検索する:findとlocateの使い方

Linux BasicsSystem ToolsLinux Commands

はじめに

Linuxを始めて最初に突き当たる問題は、ファイルの検索方法です。

このガイドは、findというコマンドの適切な使い方について説明します。これにより、さまざまなフィルターやパラメータを使用してVPS上のファイルを検索できます。また、別の方法でファイルを検索できるlocateコマンドについても簡単に触れます。

名前で検索する

ファイル検索の最も一般的な手段はファイル名の検索です。

名前からファイルを探すには、次のように入力します。

  • find -name "query"

大文字小文字を区別します。つまり、fileの検索はFileの検索とは異なります。

大文字小文字を無視して名前検索するには、次のように入力します。

  • find -iname "query"

特定の文字列を除外してファイルを検索するには、-notまたは!で検索を反転させます。!を使用する際は、findが実行される前にbashが解釈しないよう、この文字をエスケープしておく必要があります。

  • find -not -name "query_to_avoid"

または次を入力します。

  • find \! -name "query_to_avoid"

ファイルの種類で検索する

検索するファイルの種類を-typeパラメータで指定できます。次のようになります。

  • find -type type_descriptor query

ファイルの種類を指定するのに最もよく使用される記述子にはこのようなものがあります。

  • f:通常のファイル

  • d:ディレクトリ

  • l:シンボルリンク

  • c:キャラクタデバイス

  • b:ブロックデバイス

たとえば、システム上のキャラクタデバイスをすべて表示するには、このコマンドを発行します。

  • find / -type c
Output
/dev/parport0 /dev/snd/seq /dev/snd/timer /dev/autofs /dev/cpu/microcode /dev/vcsa7 /dev/vcs7 /dev/vcsa6 /dev/vcs6 /dev/vcsa5 /dev/vcs5 /dev/vcsa4 . . .

.confで終わるファイルをすべて表示するには次のように入力します。

  • find / -type f -name "*.conf"
Output
/var/lib/ucf/cache/:etc:rsyslog.d:50-default.conf /usr/share/base-files/nsswitch.conf /usr/share/initramfs-tools/event-driven/upstart-jobs/mountall.conf /usr/share/rsyslog/50-default.conf /usr/share/adduser/adduser.conf /usr/share/davfs2/davfs2.conf /usr/share/debconf/debconf.conf /usr/share/doc/apt-utils/examples/apt-ftparchive.conf . . .

時刻とサイズでフィルタリングする

Findは、結果をサイズと時刻でフィルタリングするさまざまな方法を提供します。

サイズ

サイズでフィルターするには-sizeパラメータを使用します。

値の後ろにカウント方法を示す接尾辞を付けて単位を指定します。一般的なオプションは次のとおりです。

  • c: Byte

  • k: KByte

  • M: MByte

  • G: GByte

  • b: 512 Byteブロック

50Byteちょうどのサイズのファイルをすべて検索するには、次を入力します。

  • find / -size 50c

50Byte未満のファイルをすべて検索するには、このフォームを使用します。

  • find / -size -50c

700MByte以上のファイルをすべて検索するには、このコマンドを使用します。

  • find / -size +700M

時刻

Linuxは、Access Time、Modification Time、Change Timeに関する時刻データを保存します。

  • Access Time: ファイルが最後に読み込み、書き込みされた時刻。

  • Modification Time: ファイルの内容が最後に変更された時刻。

  • Change Time: ファイルのinodeメタデータが最後に変更された時刻。

これらの検索には-atime-mtime-ctimeパラメータを使用します。サイズの場合と同様に、+/-記号を使用して、以前/以内を指定します。

このパラメータの値は、何日前に保存されたファイルを検索するかを指定します。

1日前に内容が変更されたファイルを検索するには、次のように入力します。

  • find / -mtime 1

1日以内にアクセスしたファイルを検索するには、次のように入力します。

  • find / -atime -1

メタ情報の最終変更日から3日以上経過したファイルを検索するには、次のように入力します。

  • find / -ctime +3

類似のパラメータを使用して、日数ではなく分数を指定することもできます。

  • find / -mmin -1

これにより、1分以内に内容が変更されたファイルがわかります。

また、Findを使用して参照ファイルとの比較を行い、新しい方のファイルを返すこともできます。

  • find / -newer myfile

所有者やパーミッションで検索する

ファイルの所有者やグループ所有者でファイルを検索することもできます。

これを行うには、それぞれ-userパラメータと-groupパラメータを使用します。「syslog」ユーザーが所有するファイルを検索するには次を入力します。

  • find / -user syslog

同様に、「shadow」グループが所有するファイルを指定するには次のように入力します。

  • find / -group shadow

また、特定のパーミッションでファイルを検索することもできます。

あるパーミッションに完全一致するファイルをマッチさせる場合は、次の体裁で入力します。

  • find / -perm 644

この場合、指定されたパーミッションと完全に一致するファイルがマッチします。

これらのパーミッション以上のファイルを指定するには、次の体裁で入力します。

  • find / -perm -644

この場合、指定より上のパーミッションを持つファイルがマッチします。このインスタンスでは、パーミッション「744」のファイルがマッチします。

階層でフィルタリングする

このセクションでは、一時ディレクトリにディレクトリ構造を作成します。このディレクトリ構造に、3階層のディレクトリと、1階層目に10個のディレクトリを配置します。各ディレクトリ(一時ディレクトリを含む)には10個のファイルと10個のサブディレクトリを配置します。

次のコマンドでこの構造を作成します。

  • cd
  • mkdir -p ~/test/level1dir{1..10}/level2dir{1..10}/level3dir{1..10}
  • touch ~/test/{file{1..10},level1dir{1..10}/{file{1..10},level2dir{1..10}/{file{1..10},level3dir{1..10}/file{1..10}}}}
  • cd ~/test

lscdで各ディレクトリを自由に確認して回り、その構造を把握してください。終わったら、testディレクトリに戻ります。

  • cd ~/test

この構造から特定のファイルを返す方法について見ていきます。比較のためにまず、通常の名前検索で例を試してみましょう。

  • find -name file1
Output
./level1dir7/level2dir8/level3dir9/file1 ./level1dir7/level2dir8/level3dir3/file1 ./level1dir7/level2dir8/level3dir4/file1 ./level1dir7/level2dir8/level3dir1/file1 ./level1dir7/level2dir8/level3dir8/file1 ./level1dir7/level2dir8/level3dir7/file1 ./level1dir7/level2dir8/level3dir2/file1 ./level1dir7/level2dir8/level3dir6/file1 ./level1dir7/level2dir8/level3dir5/file1 ./level1dir7/level2dir8/file1 . . .

結果がたくさん表示されます。出力をカウンタにパイプすると、計1111個の結果があるのがわかります。

  • find -name file1 | wc -l
Output
1111

これでは結果が多すぎて、ほとんどの場合役に立たないでしょう。絞り込み検索をしてみましょう。

検索するディレクトリの最大の深さを指定できます。

  • find -maxdepth num -name query

「レベル1」ディレクトリかそれ以上の階層でのみ「file1」を検索するには、最大深さ2(トップレベルディレクトリ1、レベル1ディレクトリ1)を指定します。

  • find -maxdepth 2 -name file1
Output
./level1dir7/file1 ./level1dir1/file1 ./level1dir3/file1 ./level1dir8/file1 ./level1dir6/file1 ./file1 ./level1dir2/file1 ./level1dir9/file1 ./level1dir4/file1 ./level1dir5/file1 ./level1dir10/file1

これでとても管理しやすい一覧になりました。

現在のディレクトリ配下の、一定の階層から先にすべてのファイルが存在するとわかっていれば、最小ディレクトリを指定することもできます。

  • find -mindepth num -name query

これにより末端ディレクトリのファイルだけを検索できます。

  • find -mindepth 4 -name file
Output
./level1dir7/level2dir8/level3dir9/file1 ./level1dir7/level2dir8/level3dir3/file1 ./level1dir7/level2dir8/level3dir4/file1 ./level1dir7/level2dir8/level3dir1/file1 ./level1dir7/level2dir8/level3dir8/file1 ./level1dir7/level2dir8/level3dir7/file1 ./level1dir7/level2dir8/level3dir2/file1 . . .

ここでも、分岐ディレクトリ構造の為、多数の結果(1000)が返されます。

最小・最大階層パラメータを組み合わせれば、焦点を狭い範囲に絞り込めます。

  • find -mindepth 2 -maxdepth 3 -name file
Output
./level1dir7/level2dir8/file1 ./level1dir7/level2dir5/file1 ./level1dir7/level2dir7/file1 ./level1dir7/level2dir2/file1 ./level1dir7/level2dir10/file1 ./level1dir7/level2dir6/file1 ./level1dir7/level2dir3/file1 ./level1dir7/level2dir4/file1 ./level1dir7/file1 . . .

Findコマンドの実行と組み合わせ

-execパラメータを使用すると、すべての検索コマンド上で任意のヘルパーコマンドが実行できます。このように呼び出します。

  • find find_parameters -exec command_and_params {} \;

{}は、findで合致したファイルのプレースホルダーです。\;は、findにコマンドの終わりを示します。

たとえば、前のセクションで見たファイルのパーミッション644664に変更します。

  • cd ~/test
  • find . -type f -perm 644 -exec chmod 664 {} \;

また、ディレクトリのパーミッションも次のように変更できます。

  • find . -type d -perm 755 -exec chmod 700 {} \;

異なる結果を連結させるには、-andまたは-orコマンドを使用します。省略されていれば-andと想定します。

  • find . -name file1 -or -name file9

Locateでファイルを検索する

findの代替コマンドとして、locateコマンドがあります。このコマンドの方が早いことが多く、ファイルシステム全体の検索が容易になります。

このコマンドは、DebianまたはUbuntuにaptでインストールできます。

  • sudo apt install mlocate

CentOSでは、dnfを使用します。

  • sudo dnf install mlocate

locatefindより早いのは、それがファイルシステムのファイルのデータベースに依存しているためです。

データベースは通常、cronスクリプトで1日に一度更新されますが、次を入力して手動でも更新できます。

  • sudo updatedb

このコマンドを今すぐ実行します。最近取得したファイルや作成されたばかりのファイルを検索するなら、データベースを常に最新にしておく必要があります。

locateでファイルの検索に使用する構文はこれだけです。

  • locate query

出力をフィルターする方法がいくつかあります。

たとえば、クエリ自体に含まれるファイルのみを返すなら、上位ディレクトリ付きでファイルを一つ一つ返すのではなく、-bを使用して「basename」だけを検索できます。

  • locate -b query

locateが、ファイルシステムにまだ存在する(直近のupdatedbコールと現在のlocate コール間で削除されなかった)結果のみを返すようにするには、-eフラグを使用します。

  • locate -e query

locateでカタログ化された情報を統計表示するには、-Sオプションを選択します。

  • locate -S
Output
Database /var/lib/mlocate/mlocate.db: 3,315 directories 37,228 files 1,504,439 bytes in file names 594,851 bytes used to store database

まとめ

find、locateの両コマンドとも、システム上のファイルの検索手段としてお勧めします。状況に応じてどちらのツールが適当かご自身で判断してください。

find、locateの両コマンドとも、他のユーティリティとパイプラインでつないで増強できる、パワフルなコマンドです。wcsortgrepなどのコマンドを使用してフィルタリングを試しましょう。

Creative Commons License