URI 萬用字元

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

萬用字元

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。許多指令都允許您使用旗標指定專案。如果指令不含專案旗標,或不支援使用專案旗標,則比對範圍僅限預設專案中的 bucket。

  • 殼層 (例如 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 會要求伺服器提供 bucket 根目錄中的完整物件清單,然後篩選出名稱結尾為 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=/
    

    萬用字元需要的 bucket 清單越多,速度就越慢,成本也越高。所需值區清單數量會隨著以下因素增加:

    • 萬用字元元件的數量 (例如 gs://bucket/a??b/c*/*/d 有 3 個萬用字元元件);

    • 符合各個元件的子目錄數量;以及

    • 結果數量 (如果結果數量過多,系統會實作分頁功能,並為每個結果指定標記)。

    如要使用路徑中段的萬用字元,可以改用遞迴萬用字元,例如:

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

    這會比 gs://bucket/*/obj5 比對更多物件 (因為會跨目錄),但會使用不含分隔符號的值區清單要求 (這表示值區要求較少,但會列出整個值區並在本機篩選,因此可能需要大量網路流量)。