URI 萬用字元

Google Cloud CLI 支援使用 URI 萬用字元處理檔案、值區和物件。萬用字元可讓您有效處理符合指定命名模式的檔案群組。本頁面說明支援的萬用字元,以及在指令中使用萬用字元時的重要注意事項。

萬用字元

gcloud CLI 支援下列萬用字元:

字元 說明
* 比對目前目錄層級中的零個或多個字元。舉例來說,cp gs://my-bucket/abc/d* 會比對物件 abc/def.txt,但不會比對物件 abc/def/g.txt。如果是 ls 等列出指令,如果結尾的 * 與目前目錄層級的子目錄相符,系統也會列出子目錄的內容。
** 比對目錄界線的零個或多個字元。做為本機檔案路徑的一部分時,** 萬用字元一律應緊接在目錄分隔符號後面。舉例來說,my-directory/**.txt 是有效值,但 my-directory/abc** 無效。
? 比對單一字元。舉例來說,gs://bucket/??.txt 只會比對後面接有 .txt 的兩個字元。
[CHARACTERS] 比對任何指定字元。舉例來說,gs://bucket/[aeiou].txt 會比對包含單一母音字元,後面接著 .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 開頭的檔案。

行為注意事項

在下列情況下使用萬用字元可能會導致非預期的行為:

  • 在 bucket 名稱中使用萬用字元時,系統只會比對單一專案中的 bucket。許多指令都允許您使用旗標指定專案。如果指令未包含專案標記,或不支援使用專案標記,則比對範圍僅限於預設專案中的 buckets。

  • Shell (例如 bash 和 zsh) 可能會嘗試展開萬用字元,再將引數傳遞至 gcloud CLI。如果萬用字元應參照雲端物件,這可能會導致令人意外的「找不到」錯誤。舉例來說,殼層可能會嘗試在本地電腦上展開萬用字元 gs://my-bucket/*,但這不會比對到任何本機檔案,導致指令失敗。

    此外,部分殼層會在萬用字元集內加入其他字元。舉例來說,如果使用 zsh 並啟用 extendedglob 選項,系統會將 # 視為特殊字元,這與該字元在參照版本化物件時的用途衝突 (請參閱「還原非目前物件版本」一文中的範例)。

    為避免發生這些問題,請在萬用字元運算式前後加上單引號 (Linux) 或雙引號 (Windows)。

  • 嘗試指定含有萬用字元的檔案名稱不會成功,因為指令列工具會嘗試展開萬用字元,而不是將其做為字面字元使用。舉例來說,執行下列指令:

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

    絕不會複製名為 file[1] 的本機檔案。gcloud CLI 一律會將 [1] 視為萬用字元。

    gcloud CLI 不支援「原始」模式,因此無法處理含有萬用字元的檔案名稱。對於這類檔案,您應使用其他工具 (例如 Google Cloud 控制台),或使用萬用字元擷取檔案。舉例來說,如要擷取名為 file[1] 的檔案,可以使用下列指令:

    gcloud storage cp './file*1*' gs://my-bucket
  • 根據標準 Unix 行為,萬用字元 * 只會比對開頭不是 . 字元的檔案 (以免與所有 Unix 目錄中的 ... 目錄混淆)。透過檔案系統 URI 使用萬用字元時,gcloud CLI 會提供相同的行為,但透過雲端 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 的物件。當您使用含有數千個以上物件的 bucket 時,這種效率考量就變得越來越明顯。有時可以設定物件名稱,使其符合預期的萬用字元比對模式,藉此提高伺服器端前置字元要求的效率。

  • 假設您有一個包含下列物件的值區:

    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 更多物件 (因為跨目錄),但會使用無分隔符的 bucket 清單要求實作 (這表示 bucket 要求較少,但會列出整個 bucket 並在本機篩選,因此可能需要相當多的網路流量)。