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
开头的所有文件。
行为注意事项
在以下几种情况下,使用通配符可能会导致意外行为:
在存储桶名称中使用通配符时,匹配项仅限于单个项目中的存储桶。许多命令都允许您使用标志指定项目。如果命令不包含项目标志或不支持使用项目标志,则匹配项仅限于默认项目中的存储桶。
Shell(如 bash 和 zsh)会尝试在将参数传递给 gcloud CLI 之前扩展通配符。如果通配符应该引用云对象,这可能会导致意外的“未找到”错误。例如,shell 可能会尝试扩展本地机器上的通配符
gs://my-bucket/*
,它不会匹配任何本地文件,从而导致命令失败。此外,某些 shell 的通配符字符集中包含其他字符。例如,如果您在启用 extendedglob 选项的情况下使用 zsh,它会将
#
视为特殊字符,这与引用有版本控制的对象时该字符的使用形成冲突(请参阅恢复非当前对象版本中的示例)。为避免这些问题,请使用英文单引号(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 提供此相同行为,但对 Cloud 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
(因为它跨目录)更多,但会使用分隔符更少的存储分区列出请求(这意味着存储分区请求减少,但它会列出整个存储分区并进行本地过滤,因此可能需要大量的网络流量。)