web-dev-qa-db-ja.com

ダブルアスタリスクのワイルドカードとはどういう意味ですか?

次のコマンドを試しましたが、解釈に問題があります。

ls **

しかし、何が出力されているのか、なぜそれが結果なのか、正確にはわかりません。

48
Mike Blair

おそらく、現在のディレクトリでのみ一致する単一の**とは対照的に、*に再帰的な一致を行わせるいくつかのシェルの特別な機能を使用しています。

ワイルドカード*は、現在のディレクトリ内の任意のファイルまたはディレクトリ(名前が.で始まらない)と一致します。

使用しているシェルと設定に応じて、**may*と同等です。ゼロ個以上の文字の後にゼロ個以上の文字が続く場合がありますが、これはゼロ個以上の文字が1回だけ一致する場合と同じです。

ただし、一部のシェルでは、一部の設定により、***の再帰バージョンであり、現在のディレクトリとサブディレクトリ内のすべてのファイルとディレクトリに一致します。

bash manual の引用:

「*」
ヌル文字列を含む任意の文字列と一致します。 「globstar」シェルオプションが有効で、ファイル名展開コンテキストで「*」が使用されている場合、単一のパターンとして使用される2つの隣接する「*」は、すべてのファイルと0個以上のディレクトリおよびサブディレクトリに一致します。 「/」が続く場合、2つの隣接する「*」はディレクトリとサブディレクトリのみに一致します。

これは、globstarオプションが次の方法で設定されている場合にのみ機能します。

shopt -s globstar

(デフォルトでは無効になっています)、bashの比較的最近のバージョンのみです。

Zshもこの構文をサポートしていると思います。

ワイルドカードは、lsコマンドではなく、シェルによって展開されることに留意することが重要です。 ls **、またはls *.txtと入力すると、lsコマンド自体は*文字を認識しません。コマンドラインでリスト全体を入力したかのように、ファイルの展開されたリストのみが表示されます。

117
Keith Thompson

この特定のワイルドカードの正確な動作は他の回答で十分にカバーされていますが、一般的なケースに関する情報が役立つ場合があります。

この動作はlsに限定されず、「グロビング」と呼ばれます。これは、既存のファイル名との一致に基づいたパターンの拡張です。これらのパターンは正規表現構文を使用しないことに注意することが重要です。

シェルは、プログラムに送信される前に引数を前処理します。一般に拡張には複数のレベルがあり、これらの一部にはグロビングが含まれます。

ファイルglobパターンで利用可能な他のワイルドカードに関する詳細情報の優れたリソースは、unixのマンページです。 globのオンラインバージョンは here にあります。

最後に、特に他のシェル拡張グッズ(この場合はbashシェルによって提供されるもの)と組み合わせた場合、これがあなたにできることの簡単な例です。この例で使用される展開に関する情報は、 初心者向けBash Guide -タイトルに関係なく、私のgotoリソースにあります。

ls *{01..04}.{txt,csv}ls *01.txt *01.csv *02.txt *02.csv *03.txt *03.csv *04.txt *04.csvになります

これは次のようなものを出力できます:

input_01.txt input_02.txt input_03.txt input_04.txt output_01.csv output_02.csv output_03.csv output_04.csv

これらをスキップしながら:

input_05.txt input_06.txt input_07.txt input_08.txt input_09.txt input_10.txt output_05.csv output_06.csv output_07.csv output_08.csv output_09.csv output_10.csv

些細な例ですが、この動作がlsに固有ではないことがわかっている場合は、mvcprsyncなどと組み合わせるとユーティリティを想像できます。

6
Morgen

DOS dirコマンドと同様に、lsコマンドの機能はファイルとディレクトリをリストすることです。リストされるものがファイルの場合、コマンドは単にファイルをリストするだけで、大したことはありません。リストされるものがフォルダーの場合、コマンドはフォルダーのcontentsをリストします。また、引数なしでlsコマンドだけを使用する場合、デフォルトのリストは作業ディレクトリ、つまり現在のフォルダーです。 (また、現在のフォルダーの名前は常に.なので、裸のlsコマンドはls .と同等です。)

例:現在のフォルダーにはfile_001という名前のファイル、folder_002という名前のフォルダーがあり、フォルダーにはpicture_003およびpicture_004という名前のファイルがあります。 lsと入力するとfile_001 folder_002が表示され、ls folder_002と入力するとpicture_003 picture_004と表示されます。

Unixでは、ワイルドカード処理はシェルによって実行されます。 ls **と入力すると、シェルは**を処理し、lsコマンドを実行する前に、**を一致したすべてのファイル/フォルダーの名前に置き換えます。 *ワイルドカードはすべてのファイルまたはフォルダーに一致します。**を使用すると、名前がすべてで始まり、すべてで終わるすべてのファイルまたはフォルダーに一致するため、機能的には*と同等です。)

この場合、lsコマンドを実行すると、コマンドライン引数は、すべて自分で入力したかのように、現在のフォルダー内のすべてのファイルとフォルダーのリストになります。したがって、この例では、ls file_001 folder_002コマンドを実行しています。 lsコマンドがコマンドラインを処理するとき、最初のアイテムはファイルであるため、単にファイルをリストし、2番目のアイテムはフォルダーであるため、フォルダーの内容をリストします。さらに、このコマンドは複数のものを一覧表示するため、フォルダーの名前を含むラベルを印刷するため、出力一覧のフォルダーのコンテンツを他の一覧からも区別できます。その結果、コマンドls **の出力は次のようになります。

file_001

folder_002:
picture_003   picture_004`

しかし、私は興味があります。コマンドls **を試すことを示唆しているガイド、書籍、またはドキュメントは何ですか?