URI ワイルドカード

Google Cloud CLI では、ファイル、バケット、オブジェクトに URI ワイルドカードを使用できます。ワイルドカードを使用すると、指定した名前のパターンに一致するファイル グループを効率的に処理できます。このページでは、サポートされているワイルドカードと、コマンドでワイルドカードを使用する際の重要な考慮事項について説明します。

ワイルドカード文字

gcloud CLI は、次のワークフローをサポートします。

文字 説明
* 現在のディレクトリ レベル内の 0 個以上の文字に一致します。たとえば、cp gs://my-bucket/abc/d* はオブジェクト abc/def.txt と一致しますが、オブジェクト abc/def/g.txt とは一致しません。一覧表示のコマンド(ls など)では、末尾の * が現在のディレクトリ レベルのサブディレクトリと一致する場合、そのサブディレクトリの内容も一覧表示されます。
** ディレクトリの境界を超えて 0 個以上の文字に一致します。ローカル ファイルパスの一部として使用する場合、** ワイルドカードは常にディレクトリ区切り記号が直前に配置される必要があります。たとえば、my-directory/**.txt は有効ですが、my-directory/abc** は無効です。
? 1 文字に一致します。たとえば、gs://bucket/??.txt は、任意の 2 文字の後に .txt が続くオブジェクトにのみ一致します。
[CHARACTERS] 指定した任意の文字に一致します。たとえば、gs://bucket/[aeiou].txt は、1 つの母音文字の後に .txt が続くオブジェクトに一致します。
[CHARACTER_RANGE] 任意の文字範囲に一致します。たとえば、gs://bucket/[a-e].txt は文字 a、b、c、d、e の後に .txt が続くオブジェクトに一致します。

次のように、ワイルドカードを組み合わせて、より複雑なパターンに一致させることもできます。

gs://*/[a-m]??.j*g

結果で非現行バージョンのオブジェクトを返すフラグがコマンドに含まれていない場合、これらのワイルドカードはライブ オブジェクト バージョンにのみ一致します。

gcloud CLI では、オブジェクト名とファイル名の両方に同じワイルドカードを使用できます。たとえば、次のコマンドを実行します。

gcloud storage cp data/abc* gs://bucket

ローカル ファイル システムの data ディレクトリにある abc で始まるすべてのファイルに一致します。

動作に関する考慮事項

ワイルドカードを使用すると、予期しない動作が生じることがあります。

  • バケット名にワイルドカードを使用する場合、比較検査は 1 つのプロジェクト内のバケットに制限されます。多くのコマンドでは、フラグを使用してプロジェクトを指定できます。コマンドにプロジェクト フラグが含まれていないか、プロジェクト フラグの使用がサポートされていない場合、比較検査はデフォルト プロジェクトのバケットに限定されます。

  • シェル(bash や zsh など)は、gcloud CLI に引数を渡す前にワイルドカードを展開しようとします。ワイルドカードがクラウド オブジェクトを参照しようとした場合、「Not found」エラーが発生する可能性があります。たとえば、シェルがローカルマシンでワイルドカード gs://my-bucket/* を展開しようとすると、ローカル ファイルと一致しないため、コマンドが失敗します。

    また、一部のシェルでは、ワイルドカード文字セットに他の文字が含まれています。たとえば、extendedglob オプションを有効にして zsh を使用すると、# が特殊文字として扱われ、バージョニングされたオブジェクトを参照するための使用と競合します(例については、非現行バージョンのオブジェクトを復元するをご覧ください)。

    この問題を回避するには、ワイルドカード式を単一引用符(Linux の場合)または二重引用符(Windows の場合)で囲みます。

  • コマンドライン ツールは、ワイルドカード文字をリテラル文字として使用するのではなく展開しようとするため、ワイルドカード文字が含まれるファイル名は指定できません。たとえば、次のコマンドを実行します。

    gcloud storage cp './file[1]' gs://my-bucket

    file[1] という名前のローカル ファイルをコピーしません。代わりに、gcloud CLI は常に [1] をワイルドカードとして扱います。

    gcloud CLI は、ワイルドカード文字を含むファイル名を操作できる「raw」モードをサポートしていません。このようなファイルの場合は、別のツール(Google Cloud コンソールなど)を使用するか、ワイルドカードを使用してファイルを取り込む必要があります。たとえば、file[1] という名前のファイルを取り込むには、次のコマンドを使用します。

    gcloud storage cp './file*1*' gs://my-bucket
  • 標準の Unix の動作に従い、ワイルドカード * は、. 文字で始まらないファイルのみに一致します(すべての Unix ディレクトリ内にある ... を混同しないようにするため)。gcloud CLI では、ファイル システム URI にワイルドカードを使用した場合も同じ動作になりますが、クラウド URI ではこのように動作しません。たとえば、次のコマンドは、すべてのオブジェクトを gs://bucket1 から gs://bucket2 にコピーします。

    gcloud storage cp gs://bucket1/* gs://bucket2

    ただし、次のコマンドは、. で始まらないファイルのみをディレクトリ dir から gs://bucket1 にコピーします。

    gcloud storage cp dir/* gs://bucket1

効率性に関する考慮事項

  • 次のように、オブジェクト名の先頭以外にワイルドカードを使用すると、処理が速くなり、ネットワーク トラフィックも少なくなります。

    gs://bucket/abc*.txt

    次のように、オブジェクト名の先頭にワイルドカードを使用すると、効率が悪くなります。

    gs://bucket/*abc.txt

    gs://bucket/abc*.txt のリクエストでは、バケットのルートにあり、名前が abc で始まるオブジェクトの結果のサブセットを返すようにサーバーに依頼します。その結果の一覧をフィルタリングして、名前が .txt 終わるオブジェクトで結果のリストをフィルタします。これに対し、gs://bucket/*abc.txt の場合、サーバーはバケットのルートにあり、すべてのオブジェクトをリクエストし、名前が abc.txt で終わるオブジェクトをフィルタリングします。バケット内に数千のオブジェクトが存在している場合、この効率性は非常に大きな問題となります。サーバー側の接頭辞リクエストを効率的に処理するため、ワイルドカードの一致パターンに合わせてオブジェクトの名前を設定できる場合があります。

  • たとえば、バケットに次のオブジェクトがあるとします。

    gs://bucket/obj1
    gs://bucket/obj2
    gs://bucket/obj3
    gs://bucket/obj4
    gs://bucket/dir1/obj5
    gs://bucket/dir2/obj6

    次のコマンドを実行します。

    gcloud storage ls gs://bucket/*/obj5

    gcloud storage は、/ で区切られたトップレベルのバケットの一覧を作成し、各サブディレクトリのバケットの一覧を作成します。合計で 3 つのバケットリストを作成します。

    GET /bucket/?delimiter=/
    GET /bucket/?prefix=dir1/obj5&delimiter=/
    GET /bucket/?prefix=dir2/obj5&delimiter=/
    

    ワイルドカードで必要なバケットの一覧表示が多くなると、時間とともにコストもかかります。次の数に応じてバケットリストの数が増加します。

    • ワイルドカード コンポーネントの数(例: gs://bucket/a??b/c*/*/d には、3 つのワイルドカード コンポーネントがあります)。

    • 各コンポーネントと比較するサブディレクトリの数

    • 結果の数(結果の数が多すぎる場合は複数のページに分割され、各ページにマーカーが表示されます)。

    パスの途中でワイルドカードを使用する場合には、次のように再帰的なワイルドカードを試してください。

    gcloud storage ls gs://bucket/**/obj5

    ディレクトリの境界を超えているため、gs://bucket/*/obj5 よりも多くのオブジェクトに一致しますが、区切りのないバケットリストを使用しているので、バケット リクエストの数は少なくなります。バケット全体のリストが作成され、ローカルでフィルタリングされるので、ネットワーク トラフィックの量は多くなります。