1. 概要

Linuxで作業していると、ターミナルからファイルを検索したいことがよくあります。

組み込みのfindコマンドは、この目的で広く使用されています。 ただし、代替コマンド– fd –があります。これには、より使いやすい色付きの出力、より高速な検索速度、いくつかの便利なデフォルトなど、いくつかの追加機能があります。

このチュートリアルでは、 fdの使用方法を見ていきます。

2. インストール

fd ユーティリティは、ほとんどすべてのパッケージリポジトリで使用できます。 fd パッケージは、OpenSUSE、Fedora、またはManjaroにインストールできます。 Ubuntu 19.04以降では、fd-findパッケージをインストールできます。

$ sudo apt install fd-find

Ubuntuではコマンド名はfdfindですが、エイリアスを設定できます。

$ alias fd=fdfind

3. テストファイルの作成

この例では、一時ディレクトリにいくつかのファイルをすばやく作成しましょう。

$ mkdir -p /tmp/baeldung-fd/one /tmp/baeldung-fd/two
$ cd /tmp/baeldung-fd/
$ touch one/test-File.txt two/test-File.txt
$ echo '#!/bin/sh\n:' | tee one/.hiddenFile.sh one/test-File.sh two/.hiddenFile.sh two/test-File.sh
$ chmod +x one/test-File.sh

この手順を実行すると、通常のテキストファイル、非表示ファイル、およびシェルスクリプトがいくつか作成されます。 tee コマンドを使用して、echoコマンドの出力を4つのファイルすべてに保存しました。

また、現在の作業ディレクトリを / tmp/baeldung-fd。に設定しました。

treeコマンドを使用してディレクトリ構造を表示してみましょう。

$ tree -a
.
├── one
│   ├── .hiddenFile.sh
│   ├── test-File.sh
│   └── test-File.txt
└── two
    ├── .hiddenFile.sh
    ├── test-File.sh
    └── test-File.txt

2 directories, 6 files

4. 基本的な使用法

追加のパラメータなしで、 fd を実行して、現在のディレクトリの内容を表示できます。

$ fd
one
one/test-File.sh
one/test-File.txt
two
two/test-File.sh
two/test-File.txt

ご覧のとおり、 fdは、デフォルトでは非表示のファイルを表示しません。 この出力は、端末がサポートしている場合にも色付けされます。

fd のパワーは、私たちが適用するフィルターに由来します。 フィルタを追加するときに、 fd に現在のディレクトリではなく、そのパスを検索するように指示するパス引数を指定することもできます。

フィルタリングする方法を見てみましょう。

4.1. 正規表現

デフォルトでは、 fdは検索パターンを正規表現として扱い、大文字と小文字を区別しない検索を実行します

$ fd 'file[.]sh'
one/test-File.sh
two/test-File.sh

ここで、file[。]sh式は、大文字と小文字を区別しないfile.shを含むファイルを探していました。

ドット文字は正規表現のワイルドカードであるため、引用符で囲むために角かっこ[]で囲みました。 ただし、引用符で囲まれていないドット文字を使用して、特定のディレクトリ内の任意のファイルと一致させることができます。

$ fd . two
two/test-File.sh
two/test-File.txt

パターンを指定した場合にのみパスを指定できるため、ドット(。)はすべて一致する便利なパターンです。

4.2. ワイルドカードマッチ

正規表現の代わりに、他のシェルコマンドのように、アスタリスク(*)のようなワイルドカードを使用する場合は、 -gフラグを使用すると、ファイルのグロブまたはワイルドカードによる照合が可能になります

$ fd 'test-*.sh' -g
one/test-File.sh
two/test-File.sh

4.3. 単純な文字列の一致

正規表現の特殊文字を含む文字列を照合する必要がある場合があります。 それらを引用することはできますが、-Fフラグを使用することで、パラメーターをそのまま一致させる必要があることをで示す方が簡単です。

$ fd -F 'file.sh'
one/test-File.sh
two/test-File.sh

この単純な文字列の一致は、パターンを部分文字列として一致させることによって機能します。

4.4. 大文字と小文字を区別する検索

-s フラグを使用して、大文字と小文字を区別することができます。

したがって、 file のデフォルトの検索では、次の結果が見つかります。

$ fd file ./one
one/test-File.sh
one/test-File.txt

フラグがオンになっていると、一致しなくなります。

$ fd -s file ./one
# no match

また、パターンに大文字が含まれている場合、大文字と小文字を区別するモードが自動的に有効になります。

$ fd filE ./one
# no match

4.5. 非表示のファイルを表示する

fd は、デフォルトで非表示のファイルを省略します。 -Hフラグを使用して検索結果に非表示のファイルを含めることができます

$ fd -H file ./two
two/.hiddenFile.sh
two/test-File.sh
two/test-File.txt

5. 検索基準の指定

5.1. ファイルタイプで検索

-tフラグとファイルタイプインジケーターを使用してファイルタイプを検索できます。いくつかの一般的なファイルタイプインジケーター:

  • f、ファイル–通常のファイル
  • d、ディレクトリ–ディレクトリ
  • l、symlink –シンボリックリンク
  • x、実行可能ファイル–実行可能ファイル
  • e、空–空のファイルまたはディレクトリ

すべてのサブディレクトリを一覧表示してみましょう。 ここでは、-tフラグの後にディレクトリまたはdのいずれかを使用できます。

$ fd -t directory
one
two

-t フラグを繰り返して、いくつかのファイルタイプ基準を組み合わせることができます。 空のファイルをすべて見つけるには、-tフラグを2回使用します。

$ fd -t e -t f
one/test-File.txt
two/test-File.txt

この例では、引数eを持つ最初の-tフラグが空のファイルまたはディレクトリと一致します。 引数fを持つ2番目の-tフラグは通常のファイルと一致します。 この組み合わせにより、空の通常のファイルのリストが得られます。

5.2. ファイル拡張子で検索

-eフラグを使用して、特定の拡張子を持つファイルを検索することもできます。拡張子が sh で終わるファイルを検索するには:

$ fd -e sh
one/test-File.sh 
two/test-File.sh

-e フラグを繰り返して、複数の拡張子に一致させることもできます。 たとえば、拡張子がshまたはtxtのファイルを検索するには、次のようにします。

$ fd -e sh -e txt
one/test-File.sh
one/test-File.txt
two/test-File.sh
two/test-File.txt

5.3. フルパスのマッチング

デフォルトでは、検索パターンはファイルまたはディレクトリの名前とのみ照合されます。 -pフラグを使用すると、パターンはフルパスと照合されます

/ tmp ディレクトリで、フルパスが特定の正規表現と一致するすべてのファイルを検索してみましょう。

$ fd -p 'baeldung.*sh' /tmp 
/tmp/baeldung-fd/one/test-File.sh 
/tmp/baeldung-fd/two/test-File.sh

ご覧のとおり、正規表現はファイルの絶対パスと一致します。 これはまだ部分文字列の一致であることに注意してください。ただし、正規表現アンカー^および$を追加して、一致にそれぞれパスの開始または終了を含めることができます。

5.4. 複数の場所で検索

デフォルトでは、fdは現在のディレクトリを検索します。 特定のディレクトリで検索を実行するために、パターンの後に複数のパス引数を指定できます。

ディレクトリoneおよびtwo内のすべてのファイルを検索できます。

$ fd . ./one ./two -t f 
one/test-File.sh 
one/test-File.txt 
two/test-File.sh 
two/test-File.txt

この例には、次の3つのコンポーネントがあります。

  1. 何にでも一致するために必要なファイルパターンとして単一のドットを使用します。
  2. ./one./two は、検索するパスです。
  3. -tf は通常のファイルと一致し、結果からディレクトリを省略します。

6. 高度な使用法

6.1. シンボリックリンクをトラバースする

デフォルトでは、fdはシンボリックリンクをたどりません。 -Lフラグを使用してシンボリックリンクをトラバースできます。

まず、 ln コマンドを使用して、oneという名前のサブディレクトリのシンボリックリンクを作成しましょう。

$ ln -s one symone

次に、実行可能ファイルを検索しましょう。

$ fd -t x
one/test-File.sh

ご覧のとおり、新しく作成されたシンボリックリンクの内容は表示されません。 -L フラグを使用して、シンボリックリンクの内容を含めましょう。

$ fd -t x -L
one/test-File.sh
symone/test-File.sh

これで、シンボリックリンクの内容もわかりました。

シンボリックリンクをたどっている間、別のファイルシステムをトラバースすることを避けたい場合があります。 –one-file-systemフラグを使用すると、別のファイルシステムに入るのを防ぐことができます。 

6.2. コントロールディレクトリトラバーサルの深さ

フラグ-d、–min-depth、、および –exact-depth を使用して、ディレクトリトラバーサルの深さを制御することもできます。 いくつかのディレクトリを作成してみましょう。1つは別のディレクトリ内にあります。

$ mkdir -p ./two/sub/moresub

このコマンドはすべてのファイルとディレクトリを検索しますが、最大深度は2に制限されています。

$ fd -d 2
one 
one/test-File.sh 
one/test-File.txt 
symone 
two 
two/sub 
two/test-File.sh 
two/test-File.txt

逆に、現在のディレクトリの少なくとも2レベル下のファイルを検索するように指定できます。

$ fd --min-depth 2 
one/test-File.sh 
one/test-File.txt 
two/sub 
two/sub/moresub 
two/test-File.sh 
two/test-File.txt

そして、特定の深さで検索を実行できます。

$ fd --exact-depth 2 
one/test-File.sh 
one/test-File.txt 
two/sub 
two/test-File.sh 
two/test-File.txt

6.3. 検索結果を反転

特定のパターンに一致しないファイルまたはディレクトリのみがリストされるように、検索結果を反転したい場合があります。 -Eフラグは、指定されたグロブパターンと一致しない結果を示します。 このフラグは正規表現をサポートしていないことに注意してください。

たとえば、ワイルドカードパターン * .sh 拡張子が sh。 拡張子で終わらないファイルを検索したい場合 sh 、次のコマンドを使用できます。

$ fd -E '*.sh' -t f
one/test-File.txt
two/test-File.txt

ここで、 fd はすべてのファイルを返し、ワイルドカード*。shに一致するファイルを結果から除外しました。

6.4. サイズでフィルタリング

-Sまたは–sizeフラグを使用すると、ファイルサイズの制限を指定できます。例を使用して理解するために、ディレクトリtwoにddコマンドを使用して2KBのファイルを作成しましょう。

$ dd if=/dev/random of=./two/largefile count=4 2> /dev/null

サイズが1KB以上のファイルを検索するには、式 +1k-Sフラグを使用できます。

$ fd -S +1k 
two/largefile

結果は、 dd コマンドで作成したファイルです。これは、そのサイズが基準を満たしているためです。

逆に、 -1k を使用して、1KB以下のファイルを検索できます。

$ fd -S -1k
one/test-File.sh
one/test-File.txt
two/test-File.sh
two/test-File.txt

同様に、たとえば、バイトには b を使用でき、メガバイトにはmを使用できます。 包括的なリストは、のマニュアルページにあります。

6.5. 日付でフィルタリング

作成日、変更日、または最終アクセス日に基づいてファイルを検索する必要がある場合があります。 –changed-withinフラグと–changed-beforeフラグを使用して、変更日でフィルタリングできます。これら2つのフラグは、タイムスタンプと期間の両方を引数として受け入れます。

期間は次のような単位で指定できます 、 また 。 期間単位の複数形を使用することもできます。

$ fd -t x --changed-before "2020-09-01 11:00:00"
one/test-File.sh
$ fd -t x --changed-within 2day
one/test-File.sh
$ fd -t x --changed-within 2days
one/test-File.sh

ただし、 fd は、作成日または最終アクセス日による検索をサポートしていません。

7. 検索結果でコマンドを実行する

ファイル検索の結果を処理したい場合があります。 結果をxargsに渡して、結果セットに対していくつかのコマンドを実行できます。 ただし、 fd を使用すると、コマンドを直接呼び出すことができます。 コマンドを実行する前に、次の式が展開されます。

  • {} 道
  • {。}ファイル拡張子のないパス
  • {/}ベース名
  • {/。}ファイル拡張子なしのベース名
  • {//}親ディレクトリ

7.1. バッチ実行

-Xフラグを指定して結果セット全体に対してコマンドを1回だけ実行できます。このモードでは、fdは検索結果を引数のリストとして指定されたコマンドに渡します。

結果をfileコマンドに渡します。このコマンドは、コマンドラインにファイルの種類を出力します。

$ fd -t f -X file
one/test-File.sh:  POSIX shell script, ASCII text executable 
one/test-File.txt: empty 
two/largefile:     data 
two/test-File.sh:  POSIX shell script, ASCII text executable 
two/test-File.txt: empty

ご覧のとおり、上記のコマンドは、すべての引数が一度に渡される次のコマンドと同等です。

$ file one/test-File.sh one/test-File.txt two/largefile two/test-File.sh two/test-File.txt

7.2. 繰り返し実行

一方、-xフラグを使用して結果セットの各エントリに対してコマンドを実行できます。結果セットの各エントリに対して特定のコマンドを実行する方法を理解するために、[ X196X]-各ファイルのバックアップコピーを作成するためのxフラグ。

たとえば、 fd に、検索結果の各エントリで指定された形式でcpコマンドを呼び出すように指示しましょう。

$ fd -Ht f -x cp {} {}.bak

次に、拡張子が.bakの新しいファイルが作成されたことを確認しましょう。

$ fd -Ht f -e bak
one/.hiddenFile.sh.bak 
one/test-File.sh.bak 
one/test-File.txt.bak 
two/.hiddenFile.sh.bak 
two/largefile.bak 
two/test-File.sh.bak 
two/test-File.txt.bak

ご覧のとおり、-xフラグを指定してcpを実行してバックアップを作成しました。

8. findとの比較

GitHubページのbenchmarkによると、fdfindコマンドよりもはるかに高速に実行されます。 find とは対照的に、 fd は出力を色付けし、非表示のファイルを無視し、デフォルトで入力検索パターンを正規表現として扱います。

一方、 fd は、findコマンドのすべての機能をサポートしているわけではありません。 findコマンドの-pruneフラグなどの一部のオプションは、fdでは使用できません。 find コマンドを使用すると、出力のフォーマットをより細かく制御することもできます。

9. 結論

このチュートリアルでは、fdを使用してファイルを検索するいくつかの方法を検討しました。 また、いくつかのフィルター基準を使用して検索をさらに制限する方法も確認しました。 最後に、fdfindコマンドを簡単に比較しました。