通配符名称
说明
gsutil 支持适用于文件、存储桶和对象的 URI 通配符。例如,以下命令:
gsutil cp gs://bucket/data/abc* .
将复制该子目录中的所有以下对象:以 gs://bucket/data/abc 开头,后跟任意数量的字符。
通配符字符
gsutil 使用以下通配符:
- *
- 匹配当前目录级别中的任意数量的字符。例如,
gsutil cp gs://my-bucket/abc/d* .
与对象abc/def.txt
匹配,但与abc/def/g.txt
对象不匹配。在gsutil ls
的情况下,如果末尾*
匹配当前目录级别中的子目录,该子目录的内容也会列出。 - **
匹配目录边界内任意数量的字符。用作本地文件路径的一部分时,
**
通配符应始终以目录分隔符开头。例如,my-directory/**.txt
有效,但my-directory/abc**
无效。
- ?
匹配单个字符。例如,
gs://bucket/??.txt
仅匹配两个字符后跟 .txt 的对象。- [字符]
匹配任何指定字符。例如,
gs://bucket/[aeiou].txt
匹配包含一个单元音字符后跟.txt
的对象。- [字符范围]
匹配任何字符范围。例如,
gs://bucket/[a-m].txt
匹配包含字母 a、b、c、...或 m 并以.txt
结尾的对象。
您可以组合通配符来提供更强大的匹配功能,例如:
gs://*/[a-m]??.j*g
请注意,除非您的命令包含在结果中返回非当前对象版本的标志,否则这些通配符只能与活动对象版本匹配。
gsutil 支持对象和文件名使用相同的通配符。因此,例如:
gsutil cp data/abc* gs://bucket
匹配本地文件系统的 data
目录中以 abc
开头的所有文件。
使用通配符时可能会出现的意外行为
有些使用通配符的方法可能会导致意外行为:
在存储桶名称中使用通配符时,匹配项仅限于
-p
标志中指定的项目中的存储桶。某些命令(例如gsutil rm
)不支持-p
标志。如果-p
标志未用于命令,或者无法使用命令,则匹配项仅限于默认项目中的存储桶。Shell(如 bash 和 zsh)会尝试在将参数传递给 gsutil 之前扩展通配符。如果通配符应该引用云端对象,则可能会导致意外的“未找到”错误(例如,如果 shell 尝试在本地计算机上扩展通配符
gs://my-bucket/*
,则不匹配任何本地文件,且命令失败)。请注意,一些 shell 的通配符字符集中包含其他字符。例如,如果您在启用 extendedglob 选项的情况下使用 zsh,则系统会将
#
视为特殊字符,因为该字符在引用有版本控制的对象时会使用该字符并造成冲突(请参阅恢复非当前对象版本获取示例)。为避免这些问题,请使用英文单引号(Linux 上)或英文双引号(Windows 上)括住通配符表达式。
尝试指定包含通配符的文件名时操作无效,这是因为 gsutil 将试着扩展通配符,而不是以字面量字符的形式使用通配符。例如,运行命令:
gsutil cp './file[1]' gs://my-bucket
会导致 gsutil 尝试将
[1]
部分作为通配符进行匹配。支持 gsutil 以“原始”模式提供方法处理包含通配符的文件名时,会出现一个公认的问题,直到/除非该支持得到实现,否则使用 gsutil 处理此类文件名没有真正好的方法。您可以使用通配符来命名此类文件,例如将上述命令替换为:
gsutil cp './file*1*' gs://my-bucket
但这种方法一般可能不好用。
本地文件系统中“Dot”文件的不同行为
根据标准的 Unix 行为,通配符 *
仅匹配不以 .
字符开头的文件(为了避免与所有 Unix 目录中展示的 .
和 ..
目录存相混淆)。通过文件系统 URI 使用通配符时,gsutil 可提供相同的行为,但不通过 Cloud URI 提供此行为。例如,以下命令会将 gs://bucket1 中的所有对象复制到 gs://bucket2:
gsutil cp gs://bucket1/* gs://bucket2
但是,以下命令只会将不以 .
开头的文件从目录 dir
复制到 gs://bucket1:
gsutil cp dir/* gs://bucket1
效率注意事项:针对多个对象使用通配符
下面两种方法相比,前者更高效、快速,且密集型网络流量更少:使用具有非通配符对象名称前缀的通配符,例如:
gs://bucket/abc*.txt
与将通配符用作对象名称的第一部分相比,例如:
gs://bucket/*abc.txt
这是因为 gs://bucket/abc*.txt
请求要求服务器发送回存储分区根目录中对象名称以 abc
开头的结果的子集,然后 gsutil 过滤结果列表以得到名称以 .txt
结尾的对象。相比之下,gs://bucket/*abc.txt
要求服务器提供存储分区根目录中对象的完整列表,然后过滤获取名称以 abc.txt
结尾的对象。当您使用包含数千个或更多对象的存储分区时,这种效率考量会愈加明显。有时,您可以设置对象的名称,使其符合预期的通配符匹配模式,从而利用进行服务器端前缀请求的效率。如需查看示例用例,请参阅相关文档,例如 gsutil 帮助:生产。
效率注意事项:使用路径中间通配符
假设您有一个包含以下对象的存储分区:
gs://bucket/obj1
gs://bucket/obj2
gs://bucket/obj3
gs://bucket/obj4
gs://bucket/dir1/obj5
gs://bucket/dir2/obj6
如果您运行以下命令:
gsutil ls gs://bucket/*/obj5
gsutil 会执行 / 分隔的顶层存储分区列出,然后针对每个子目录执行一次存储分区列出,总共 3 次存储分区列出:
GET /bucket/?delimiter=/
GET /bucket/?prefix=dir1/obj5&delimiter=/
GET /bucket/?prefix=dir2/obj5&delimiter=/
通配符要求的存储分区列出越多,其速度越慢,费用也就越高。所需存储分区列出的次数会随下列因素增加:
通配符元素的数量(例如 “gs://bucket/a??b/c*/*/d”中包含 3 个通配符元素);
与每个元素匹配的子目录的数量;以及
结果的数量(当结果数量过大时,系统会实现分页,并为每个请求指定标记)。
如果要使用路径中间通配符,您可以尝试改用递归通配符,例如:
gsutil ls gs://bucket/**/obj5
它匹配的对象将比 gs://bucket/*/obj5
(因为它跨目录)更多,但会使用分隔符更少的存储分区列出请求(这意味着存储分区请求减少,但它会列出整个存储分区并进行本地过滤,因此可能需要大量的网络流量。)