1. 序章

このチュートリアルでは、正規表現(regex)でのコマンドfindの使用について説明します。 検索結果をさらに絞り込むために正規表現を指定する方法を見ていきます。

2. 正規表現入門書

find で正規表現を使用する方法を示す前に、それらが何であるか、およびそれらがどのように構築されるかから始めましょう。

正規表現(正規表現と略記)は、検索パターンを指定する文字シーケンスで記述される強力なツールです。これが、findと併用するとより洗練されたものになる理由です。より少ないコマンドで検索します。

正規表現と形式にはさまざまな種類があります。 以下で説明する概念は、それらの間で一貫しています。 ただし、より高度な機能には違いがあるため、使用されている正規表現の種類を知る必要があります。 find コマンドで受け入れられる正規表現のフレーバーについては、次のセクションで詳しく説明します。

2.1. 主な正規表現トークンと例

気が遠くなると思われることもありますが、正規表現は検索を改善し、コマンドラインとの対話を強化します。 基本的な知識だけで、私たちはすでにそれらから利益を得ることができます。

簡単な紹介として、複数の文字に一致する正規表現トークンがあります。

  • ピリオド():任意の文字に1回一致します(改行文字を除く):qeは文字列qwe qre 、およびqeeですが、文字列qeまたはqwweは含まれません。
  • アスタリスク( * ):先行する文字/正規表現の0回以上の出現に一致します: qw *eは文字列qeqweに一致します qwwe ですが、文字列qreではありません
  • バックスラッシュ( \ ):特殊文字をエスケープして、たとえばピリオドを検索します。 q \ .eは文字列qeと一致しますが、文字列とは一致しません qre qee、 qeまたはqwwe
  • 角かっこ( [string ] ):角かっこ内の文字列のいずれかの文字が正の一致を返します: q [we]rは文字列と一致しますqwrおよびqerですが、文字列 qr、qwer 、またはqwewerは対象外です。
  • キャレット( ^ ):角かっこ内のコンテンツを無効にします(ただし、ファイル内を検索するときに行の先頭も指定します): q [^ we] r [ X171X]は、文字列qarおよびqsrと一致しますが、文字列qwrまたはqerとは一致しません。

組み合わせて頻繁に使用される2つのトークンは。*です。これは、前の説明に基づいて、改行を除く任意の文字の0回以上の出現に一致します。つまり、任意の文字列に一致します。

3. コマンドの説明

コマンドfindの使用は、pathとsearchexpressionの2つのコンポーネントに分割できます。

find [path] [expression]

パスは検索用のディレクトリです。 式の部分には、検索基準に準拠するファイルで実行される可能性のあるアクションも含まれます。 コマンドがそこにあります探す正規表現に関連する3つのオプションがあります。 ここで、いくつかのユースケースの例を示します。 例では、次のモックアップディレクトリが使用されます。

$ tree ./
./
├── a0
├── a0.sh
├── A0.sh
├── a1
├── a1.sh
├── A1.sh
├── a2
├── ca
├── cb
├── cc
└── folder
    ├── a0
    ├── a1
    └── a0folder
        ├── a0
        └── a1

2 directories, 13 files

3.1. の使用-正規表現

最初のオプションは、-regexと正規表現です。

find [path] -regex [regular_expression]

このコマンドを使用すると、 path が検索され、regular_expressionに準拠するファイルが返されます。 regular_expressionパターンには、ルートパスディレクトリを含む完全なファイル名が含まれます。これは、現在のディレクトリを調べる場合、regular_expression\。\/[X215Xで始まる必要があることを意味します。 ](バックスラッシュを使用して特殊文字をエスケープします)。

次のコマンドは、現在のディレクトリ(\。\/ )にあり、文字 a で始まるファイル(タイプf フラグ)を検索します。 ]の後に0または1のいずれかが続きます:

$ find ./ -type f -regex '\.\/a[01].*'
./a1
./a0
./a1.sh
./a0.sh

文字aの後に0または1が続かないため、ファイルa2は返されません。 次のコマンドを使用して、現在のディレクトリの代わりに第1レベルのディレクトリを検索することもできます。

$ find ./ -type f -regex '\.\/[^/]*\/a[01][^/]*'
./folder/a1
./folder/a0

最後の2つの正規表現には2つの違いがあります。 まず、トークン [^ /] * \ / は、スラッシュ([^ /] * )とそれに続く1つのスラッシュ(\ /)を含まない文字列を参照します。文字aで始まるファイル名の前。 次に、ピリオドを [^ /] に置き換えて、文字aの後にスラッシュが表示されないことを示します。

サブディレクトリ内のファイルは正規表現を満たしていません。最初のスラッシュ(現在のディレクトリ)と直後のスラッシュの間に a という文字があります。サブディレクトリには余分なスラッシュがあります(たとえば、。/ folder / a0folder / a0 )。

最後に、すべてのサブディレクトリにすべてのファイルを含めるには、次を使用できます。

$ find ./ -type f -regex '.*a[01].*'
./folder/a0folder
./folder/a0folder/a0
./folder/a0folder/a1
./folder/a0
./folder/a1
./a0
./a1
./a0.sh
./a1.sh

3.2. の使用-iregex

2番目のオプションは-iregexです。

find [path] -iregex [regular_expression]

このコマンドは、 -regex オプションと同じ検索を実行しますが、検索パターンの大文字と小文字を無視します。 ニーモニックルールとして、コマンド -iregex は、大文字と小文字を区別しない正規表現を表します。

以前のコマンドの1つを変更して、ドットのあるファイルのみを検索すると([。]を含めることにより)、出力は次のようになります。

$ find ./ -type f -regex '\.\/a[01][.].*'
./a0.sh
./a1.sh

-regexフラグの代わりに-iregexフラグを使用した結果には、大文字のAのファイルも含まれます。

$ find ./ -type f -iregex '\.\/a[01][.].*'
./a0.sh
./A1.sh
./A0.sh
./a1.sh

3.3. の使用-regextype

最後に、オプション -regextype は、正規表現のタイプを選択します。

find [path] -regex [regular_expression] -regextype [regex_type]

コマンドfind:では、さまざまな正規表現タイプを使用できます。

  • findutils
  • emacs (特に指定がない限り、これはデフォルトのオプションです)
  • gnu-awk
  • grep
  • egrep
  • posix-awk
  • posix-基本
  • posix-egrep
  • posix-拡張

以前に定義されたトークンは、これらすべてのタイプの正規表現と互換性があります。 ただし、より高度な検索クエリでは、さまざまな正規表現タイプでさまざまな結果が生成される場合があります。 さまざまな構文の詳細を説明するための包括的なGNUWebページがあります。

4. バッシュグロブとの比較

Linuxを少しだけ使用した後、bashグロブは確かにlsのようなコマンドに現れました。 次のコマンドについて考えてみましょう。

ls *.png

.pngのフォーマット拡張子を持つすべてのファイルが一覧表示されます。 一方、コマンド:

ls M*.png

は、フォーマット拡張子が .png で、文字Mで始まるすべてのファイルを一覧表示します。 これは、動作中のbashグロブです:ファイル名の補完。 findコマンドでnameを検索する場合、Bashグロブが使用されます。

似ているように見えても、 bashグロブと正規表現は異なる構文を示し、問題を複雑にします。 最も関連性の高い2つの違いについて説明します。 ピリオド(。)は、bashグロブでは文字通りのピリオドを表しますが、正規表現では任意の1文字を表します。 この最初のコマンドは、bashグロブアプローチを示しています。

$ find ./ -type f -name 'a*.sh'
./a0.sh
./a1.sh

同じ結果を得るには、次のregex findコマンドを使用できます。

$ find ./ -type f -regex '\.\/a.*\.sh'
./a0.sh
./a1.sh

bashグロブと正規表現のもう1つの違いは、アスタリスク( * )です。bashグロブでは0個以上の文字を表しますが、regexでは前の文字の0個以上を表します。 したがって、同様のコマンドは、bashグロブを展開するか正規表現を展開するかにかかわらず動作が異なります。 bashグロブを使用する場合、次のコマンドはcで始まるすべてのファイルを返します。

$ find ./ -type f -name 'c*'
./cb
./cc
./ca

ただし、同様の検索パターンに正規表現がある場合は、名前にcのみが含まれるすべてのファイルが返されます。

$ find ./ -type f -regex '\.\/c*'
./cc

ディレクトリを検索してbashグロブまたは正規表現を使用する場合は、これらの違いに注意する必要があります。

5. 結論

このチュートリアルでは、いくつかの基本的な正規表現を適用して、 find コマンドの出力をさらに絞り込み、ディレクトリ内のファイルの検索を容易にする方法について説明しました。