find コマンドを使用すると、ユーザーはファイルを検索し、それらに対してアクションを実行できます。これは「findutils」パッケージの一部であり、すべてのディストリビューションにバンドルされています。柔軟性が高く、さまざまな条件に基づいてファイルやディレクトリを検索できます。必要に応じて、結果に対してさまざまな種類のアクションを実行することもできます。
この記事では、find コマンドの使用方法を理解します。この記事では、さまざまな例を通してその使用法についても説明します。
はじめに
find コマンドの基本構造は次のようになります:
find [paths] [expression] [actions]
find コマンドは多数のパスを取り、各パス内のファイルとディレクトリを「再帰的に」検索します。したがって、find コマンドは、指定されたパス内のディレクトリに遭遇すると、その中の他のファイルとディレクトリを探します。繰り返しますが、内部に他のディレクトリがある場合、find コマンドはそれらの内部も検索します。このプロセスは、指定したパス内のすべてのアイテムを検索するまで続きます。
デフォルトでは、find コマンドはディレクトリ内のすべてを検索します。特定の基準に基づいてそれらの一部を除外する場合は、そのための式を指定できます。
デフォルトのアクションは、すべての結果を出力することです。ただし、検索コマンドが結果に対して実行できるカスタム アクションを指定することもできます。
これらの概念は、この記事で後述するさまざまな例を見ていくうちに、より明確になります。
すべてのファイルとディレクトリを検索しています
特定のパスのすべてのディレクトリとファイルを一覧表示したいとします。たとえば、/usr/share
の内容を一覧表示する場合 ディレクトリ、実行:
find /usr/share
これにより、以下のスクリーンショットに示すように、ファイルとディレクトリのリストが表示されます。ディレクトリの内容によっては、このリストが非常に大きくなる可能性があります!
複数のディレクトリの内容を一覧表示する場合は、次のようにします。
find /usr/share /bin /usr/lib
現在の作業ディレクトリの内容を一覧表示する場合は、ピリオド (.
) パスとして:
find .
パスがない場合、find コマンドは、現在のディレクトリで動作するはずであると想定します。したがって、.
を残すことができます 単純に次を使用します:
find
名前によるアイテムの検索
前述したように、式を使用して find コマンドの結果をフィルター処理できます。このセクションでは、アイテムを名前でフィルタリングする方法を学びます。
NEWS.txt
という名前のファイルまたはディレクトリを検索する場合 /usr
の中 ディレクトリ、-name
を使用 次のように切り替えます:
find /usr -name NEWS.txt
-name
switch は大文字と小文字を区別します。探しているアイテムの正確なケースがわからない場合は、-iname
を使用できます 大文字と小文字を区別しないスイッチ:
find /usr -iname news.txt
-name
と -iname
スイッチは、プレースホルダーとして機能する特殊文字である「ワイルドカード」も受け入れます。 ?
という 2 つのワイルドカードがあります。 character は単一の不明な文字を表し、*
は character は任意の数の未知の文字 (0 を含む) を表します。
ワイルドカード文字を使用する場合は、name
を保持する必要があります /iname
一重引用符または二重引用符内のパラメーター。 *
以来 と ?
文字はシェルの特殊文字でもあり、それらを引用符で囲むと、コマンドが正しく機能することが保証されます。
例として、 /usr
内のすべてのファイルとディレクトリを検索する必要がある場合 .txt
を持つもの 名前の最後に、次を使用できます:
find /usr -name '*.txt'
名前に 4 文字を含むファイルとディレクトリを検索する場合は、次を実行します。
find /usr -name '????'
場合によっては、名前だけでなく、ファイル/ディレクトリへのフル パスを一致させたい場合があります。このような状況では、 -path
を使用できます スイッチ。例として、.txt
を持つすべてのファイルとディレクトリを検索するとします。 ただし、src
という名前のディレクトリにある場合のみ .したがって、フル パスには /src/
が含まれます。 真ん中のどこか、そして .txt
最後に。したがって、コマンドは次のようになります:
find /usr -path '*/src/*.txt'
-ipath
もあります -path
の大文字と小文字を区別しないバージョンのスイッチ .
ファイルまたはディレクトリの検索
これまで見てきたすべての例は、ファイルとディレクトリを返します。ただし、ファイルまたはディレクトリのみを検索する必要がある場合は、 -type
を使用できます スイッチ。 -type
の最も一般的なパラメーター
-
f
:ファイル -
d
:ディレクトリ -
l
:シンボリック リンク
たとえば、/usr
内のすべてのファイルを検索するには ディレクトリ、実行:
find /usr -type f
find コマンドのさまざまなスイッチを組み合わせることもできます。たとえば、すべての .txt
を検索するには /usr
のファイル ディレクトリ、使用できます:
find /usr -type f -name '*.txt'
同様に、/usr
内のディレクトリを検索するには 「python」で始まる場合は、次を使用します:
find /usr -type d -name 'python*'
空のファイルを見つける
find コマンドは -empty
をサポートしています 空のファイルとディレクトリを検索するためのフラグ。空のファイルはコンテンツを含まないファイルであり、空のディレクトリはファイルやサブディレクトリを含まないファイルです。
たとえば、ホーム ディレクトリ内の空のディレクトリの一覧を検索する場合は、次のコマンドを実行できます。
find ~ -type d -empty
一致の否定
find コマンドを使用すると、一致を「否定」することもできます。これは、検索から除外する基準がある場合に役立ちます。
例として、/usr
内のファイルを検索するとします。 .txt
を持たないディレクトリ 拡大。 -name
を否定できます 感嘆符 (!
) を追加して切り替えます ) に示すように、その前に:
find /usr -type f ! -name '*.txt'
他のスイッチを反転することもできます。したがって、ホーム ディレクトリで空でないディレクトリを見つけたい場合は、次を実行します。
find /usr -type f ! -empty
所有権に基づく検索
find コマンドは、所有権情報に基づくファイルとディレクトリの検索をサポートします。
特定のユーザーに属するファイルまたはディレクトリを見つけるには、-user
を使用できます。 スイッチ。たとえば、ユーザー booleanworld
に属するシステム上のすべてのファイルを検索する場合 、実行:
find / -type f -user booleanworld
ユーザー名の代わりに、上記のコマンドでユーザーの ID を使用することもできます。次のコマンドでユーザーの ID を調べることができます:
id -u <username>
同様に、-group
スイッチを使用すると、特定のグループに属するファイルとディレクトリを探すことができます。グループ名またはグループ ID を受け入れることもできます。次のコマンドでユーザーのグループ ID を表示できます:
id -g <username>
日時に基づくファイルの検索
アクセスまたは変更された時期によっては、ファイルの検索が必要になる場合があります。 Linux システムでは、ファイルに関連付けられた 3 種類の「時間」があります。
- 修正時間 :ファイルのコンテンツが最後に変更された時刻。
- アクセス時間 :ファイルが最後に読み取られた時刻。
- 時間を変更 :ファイル (コンテンツまたはパーミッションなどのメタデータ) が最後に変更された時刻。
変更、アクセス、または変更時間に基づいてファイルを検索するには、find コマンドに -mtime
、 -atime
と -ctime
スイッチ。これらのスイッチを使用すると、日数に基づいてファイルをフィルタリングできます。ここで、「1 日」とは 24 時間の期間を指します。
これらのフラグの使用方法を理解しましょう。例として、-mtime
を使用する場合 、次に:
-
-mtime 2
:ファイルは 2 日前 (つまり、過去 48 時間から 72 時間以内) に変更されました。 -
-mtime -2
:ファイルは 2 日以内 (つまり、過去 48 時間以内) に変更されました。 -
-mtime +2
:ファイルは 2 日以上前に変更されました (つまり、3 日以上、つまり 72 時間以降)。
したがって、/usr
でファイルを検索するには 2 日前に変更された場合は、実行:
find /usr -type f -mtime 2
-atime
と -ctime
スイッチは -mtime
とまったく同じように機能します .
1 日が少し長すぎる場合は、-mmin
も使用できます。 、 -amin
または -cmin
数分でフィルタリングできます。つまり、-amin +5
5 分以上前にアクセスされたファイルを意味します、-amin -5
ファイルが 5 分以内に変更されたことを意味します。
これらのフラグの多くを一度に使用できます。 2 日前に変更され、5 分前にアクセスされたファイルを検索するには、次を実行します。
find /usr -type f -mtime 2 -amin 5
同じフラグを繰り返すこともできます!例として、50 ~ 100 日前に変更されたファイルを検索するには、次を使用します。
find /usr -type f -mtime +50 -mtime -100
サイズに基づく検索
find コマンドには -size
があります ユーザーがサイズに基づいてファイルを検索できるように切り替えます。ファイル サイズを持つことができるのはファイルのみであるため、このスイッチを使用すると、ディレクトリは一覧表示されません。
ファイルサイズを指定するには、数字の後に単位を表す文字を付けます。次の文字を使用できます:
-
c
:バイト -
k
:キロバイト -
M
:メガバイト -
G
:ギガバイト
さらに、+
を使用できます または -
「より大きい」または「より小さい」条件を課す。
いくつかの例でこれを理解しましょう。サイズが 10 KB のシステム上のすべてのファイルを一覧表示する場合は、次を使用します。
find / -size 10k
サイズが 1 GB を超えるファイルを検索するには、次を使用します:
find / -size +1G
同様に、サイズが 10MB 未満のファイルを検索するには、次を使用します:
find / -size -10M
権限に基づく検索
find コマンドは -perm
をサポートしています アクセス許可に基づく検索を許可するように切り替えます。数値モードと記号モードの両方に基づいて検索できます。権限に慣れていない場合は、ここで概要を確認できます。
シンボリック パーミッションの使用
簡単な例から始めましょう。 /usr
内のすべてのファイルとディレクトリを検索するとします。 rwxr-xr-x
の権限を持つディレクトリ .そのためには、次を実行します:
find /usr -perm u=rwx,g=rx,o=rx
文字 u
、 g
と o
それぞれ「ユーザー」、「グループ」、「所有者」を表します。
文字 a
も使用できます すべてのユーザーに適用される権限を確認します。たとえば、権限が r-xr-xr-x
のシステム上のすべてのファイルとディレクトリを検索するには 、実行:
find /usr -perm a=rx
多くの場合、パーミッションのサブセットを照合することに関心があります。たとえば、すべてのユーザーが実行できるシステム上のファイルを検索したい場合があります。この場合、実行ビットが 3 つの権限クラスすべてに設定されていることだけが重要です。ただし、残りのビットは設定または設定解除できます。
すべてのパーミッション クラスに実行ビットを設定する必要があるため、パーミッションを a=x
と記述します。 .次に、 /
を追加します パーミッションのサブセットに一致させるつもりであることを示すために前に付けます。したがって、コマンドは次のとおりです。
find / -type f -perm /a=x
数値権限の使用
前のセクションの最初の例を考えてみましょう。これはとても簡単です — rwxr-xr-x
数値モードでは 644 なので、単純に実行できます:
find /usr -perm 644
アクセス許可のサブセットの確認は、もう少し複雑です。前述したように、誰もが実行できるファイルを検索するには、実行ビットが設定されているかどうかを確認する必要があります。他のビットは気にしません。チェックする必要があるすべてのビットには 1 を入れ、残りの部分には 0 を入れます。このプロセスで、2 進数を取得し、次に示すようにそれを 8 進数に変換します。
次に、 -
を追加します この番号の前に を付けて、パーミッションのサブセットに一致させるつもりであることを示します。したがって、コマンドは次のとおりです。
find / -type f -perm -111
アクセス権フラグに基づく検索
ここで、数値の権利フラグに基づいて検索したいとします。この目的のために、数値モードまたは記号モードのいずれかを使用できます。
例として、setuid ビットが設定されたシステム上のすべてのファイルを検索したいとします。数値モードについて学んだことをこの状況に拡張できます。この場合、値が 4 の setuid フラグのみを考慮します。ただし、パーミッション ビットは考慮しません。つまり、000 を取得します。したがって、以下を使用してこれらのファイルを検索できます。 /P>
find / -type f -perm -4000
もちろん、許可ビットをフィルタリングすることもできます。すべてのユーザーが実行できるファイルに関心があり、さらに setuid ビットが設定されている場合は、上記のコマンドで 4000 を 4111 に置き換えます。 (値 111 を取得する方法は以前に見ました。)
同様に、setgid ビットに 2000、スティッキー ビットに 1000 を使用できます。これらのビットの組み合わせをテストする場合は、値を合計します。たとえば、setuid とスティッキー ビットをテストするには、5000 (=4000 + 1000) を使用します。
シンボリック モードで同じことをしたい場合は、以下を使用できます:
find / -type f -perm /u=s
setgid ビットには、/g=s
を使用します 、スティッキー ビットには /o=t
を使用します .これらのビットの組み合わせをテストするには、/u=s,o=t
のようにカンマで区切ります。 .
トラバーサルの深さを制限する
前述したように、find コマンドは項目を再帰的に検索します。ただし、得られる結果が非常に大きくなる可能性があるため、find コマンドで検索できる深さを制限する必要がある場合があります。これは -maxdepth
で行うことができます 切り替えます。
次のコマンドを実行すると、表示されるすべてのアイテムの深さが 3 レベル以下であることがわかります:
find / -maxdepth 3
他の状況では、最小深度に制限を設定したい場合があります。 find コマンドは -mindepth
もサポートしています この目的のために切り替えます。したがって、実行すると:
find / -mindepth 3
find コマンドの論理演算
前のセクションでは、find コマンドでサポートされているフラグを見てきました。また、さまざまなフラグを組み合わせて無効にする方法も見てきました。場合によっては、より強力な構造が必要になります。
検索コマンドは、-a
を使用した「and」および「or」条件をサポートしています および -o
スイッチ。また、括弧 ()
を使用して式の一部をグループ化することもサポートしています .ただし、括弧もシェルの特殊文字であるため、一重引用符または二重引用符で囲む必要があります。さらに、複数のフラグを次々に指定すると、find コマンドは自動的に「and」を想定します。
/usr
内のディレクトリを検索する、前に見た例を考えてみましょう。 「パイソン」で始まるもの。そこで、次のコマンドを使用しました:
find /usr -type d -name 'python*'
次のように「and」を明示的に書くこともできます:
find /usr -type d -a -name 'python*'
ここで、別の例を考えてみましょう。過去 5 分間または 50 日より前に変更されたシステム上のファイル/ディレクトリを検索するとします。このコマンドでは、次のように「or」演算子を使用します。
find / -mmin -5 -o -mtime +50
次に、上記の問題に追加の制限を課すとします。つまり、ファイルのみを検索したいとします。まず、グループ内の変更されたファイルをフィルタリングするための条件を保持します。次に、ファイルを検索する条件で「AND」します。したがって、最終的なコマンドは次のとおりです。
find / '(' -mmin -5 -o -mtime +50 ')' -a -type f
-a
以降 は暗黙的であるため、上記のコマンドから除外することもできます。
行動する
これまでのところ、すべての find コマンドは端末に結果を出力します。通常、これらのアイテムのコピーや削除など、これらの結果に対して何らかのアクションを実行したいと考えています。幸いなことに、find コマンドは、これらの結果に対する「アクション」の実行もサポートしています。
デフォルトのアクションは、すべての結果を出力することです。 -print
を追加することでこれを確認できます 検索コマンドの最後に切り替えます。他にもたくさんのアクションがあります。以下に、最も役立つものをいくつか見ていきます。
ファイルの削除
ファイルまたはディレクトリを削除するには、-delete
を使用します アクション。ファイルとディレクトリの両方で機能します。たとえば、ホーム ディレクトリからすべての空のディレクトリを削除する場合は、次を実行します。
find ~ -type d -empty -delete
コマンドの実行
find コマンドは、-exec
を使用したカスタム コマンドの実行もサポートしています。 切り替えます。
すべての MP3 オーディオをホーム ディレクトリから外付けハード ドライブにバックアップするとします。外付けハードドライブが /media/MyDrive
で利用可能であると仮定します .単一のファイルをコピーするには、次を使用します:
cp <path to file> /media/MyDrive
すべてのファイルをコピーするには、次のコマンドを使用できます。
find ~ -type f -name '*.mp3' -exec cp {} ';'
ここでは、中かっこのペア ({}
) ファイルへのパスのプレースホルダーとして機能します。コマンドの終了位置をファイル コマンドに伝えるために、セミコロン (;
) を使用します。 )。ただし、これはシェルの特殊文字でもあるため、一重引用符で囲みます。
find コマンドは、条件に一致するファイルを見つけるたびに、中かっこを実際のパスに置き換えて、コマンドを実行します。だから、cp
コマンドはすべての MP3 ファイルに対して実行されます。
別の重要な用途を見てみましょう — 多くのファイルから文字列を見つけることです。ファイル内の文字列「hello」を見つけるには、次のように grep を使用します。
grep hello <file name>
grep
に精通している場合 、次のようなコマンドを書きたくなるかもしれません:
find ~ -type f -exec grep hello {} ';'
ただし、このコマンドを使用すると、問題がすぐにわかります。文字列「hello」を含むファイルのリストが必要です。ただし、一致した行のリストを取得します。幸い、grep
-l
があります これにより、一致するファイルのパスが出力されます。したがって、コマンドは次のようになります:
find ~ -type f -exec grep -l hello {} ';'
コマンドの実行:別のバリアント
圧縮ファイルを作成するとします。 music.tar.gz
という名前の Gzip 圧縮ファイルを作成するには 、次のように実行します:
tar -czf music.tar.gz <list of files>
ここで、ホーム ディレクトリ内のすべての MP3 ファイルを 1 つの圧縮ファイルに圧縮するとします。おそらく、次のように思いつくでしょう:
find ~ -type f -name '*.mp3' -exec tar -czf music.tar.gz {} ';'
ただし、music.tar.gz
を開くと、 ファイルを見ると、MP3 ファイルが 1 つしかないことがわかります。 find
を覚えておいてください 新しいファイルが見つかるたびにコマンドを実行します。そのため、以前のファイルは毎回新しいアーカイブで上書きされました。
find
を伝える方法があれば、私たちの問題はすべて解決できます。 ファイルのリストを tar
に渡す 、すべてのファイルが見つかった後。これは、-exec
の 2 番目の亜種の場所です。 ;
でコマンドを終了する代わりに、スイッチが入ります。 、 +
を使用します そのように:
find ~ -type f -name '*.mp3' -exec tar -czf music.tar.gz {} +
ディレクトリでのコマンドの実行
ファイル/ディレクトリが存在するディレクトリでコマンドを実行すると便利な場合があります。 find コマンドには -execdir
があります これを行うスイッチ。 -exec
に似ています 他のすべての方法で、 +
さえ持っています と ;
ファイル情報の表示
ファイル/ディレクトリに関する情報 (パーミッションやサイズなど) を表示したい場合は、-ls
を使用できます。 スイッチ。たとえば、システム上の 1GB を超えるファイルの詳細を表示する場合は、次のコマンドを実行します:
find / -type f -size +1G -ls
エラー メッセージの削除
検索コマンドのいくつかを試しているときに、「許可が拒否されました」などのエラーが発生する場合があります。これらのエラー メッセージを /dev/null
にリダイレクトすることで非表示にすることができます 、示されているように:
find [paths] [expression] [actions] 2>/dev/null
結論
この記事では、ほとんどのユースケースをカバーする例とともに、find コマンドの使用方法を見てきました。詳細を読みたい場合は、man find
と入力して man ページを読むことができます。