通配符名称

说明

gsutil 支持 URI 通配符。例如,以下命令:

gsutil cp gs://bucket/data/abc* .

将复制该子目录中的所有以下对象:以 gs://bucket/data/abc 开头,后跟任意数量的字符。

逐一按目录与递归通配符

“*”通配符最多只会匹配到一个子目录内的一个路径的末尾。举例来说,如果存储分区包含名为 gs://bucket/data/abcd、gs://bucket/data/abcdef 和 gs://bucket/data/abcxyx 的对象,以及一个子目录中的对象 (gs://bucket/data/abc/def),上述 gsutil cp 命令将匹配前 3 个对象名称,但不匹配最后一个。

如果您希望跨目录边界匹配,请使用“**”通配符:

gsutil cp gs://bucket/data/abc** .

将匹配上述全部四个对象。

请注意,gsutil 支持对象和文件名使用相同的通配符。 因此,例如:

gsutil cp data/abc* gs://bucket

将匹配本地文件系统中的所有名称。大多数命令 shell 亦支持通配符,因此如果运行上述命令,shell 有可能在运行 gsutil 之前扩展匹配内容。但是,大多数 shell 不支持递归通配符 ('**'),但您可以使用英文单引号括住参数,使其在传递给 gsutil 之前不被 shell 解释,从而使 gsutil 的通配符支持用于此类 shell:

gsutil cp 'data/abc**' gs://bucket

存储分区通配符

您可以为单个项目中的存储分区名称指定通配符。例如:

gsutil ls gs://data*.example.com

将列出默认项目中名称以“data”开头且以“.example.com”结尾的所有存储分区的内容。-p 选项可用于指定非默认项目。例如:

gsutil ls -p other-project gs://data*.example.com

您还可以综合运用存储分区和对象名称通配符。例如,以下命令将移除默认项目中所有 Cloud Storage 存储分区中的所有“.txt”文件:

gsutil rm gs://*/**.txt

其他通配符

除“*”外,您还可以使用以下通配符:

?
匹配单个字符。例如,“gs://bucket/??.txt”仅匹配两个字符后跟 .txt 的对象。
[字符]
匹配任何指定字符。例如,“gs://bucket/[aeiou].txt”匹配包含一个单元音字符后跟 .txt 的对象
[字符范围]
匹配任何字符范围。例如,“gs://bucket/[a-m].txt”匹配包含字母 a、b、c、...或 m 并以 .txt 结尾的对象。

您可以组合通配符来提供更强大的匹配功能,例如:

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

使用通配符时可能会出现的意外行为

有些使用通配符的方法可能会导致意外行为:

  1. Shell(如 bash 和 zsh)会尝试在将参数传递给 gsutil 之前扩展通配符。如果通配符应该引用云端对象,则可能会导致意外的“未找到”错误(例如,如果 shell 尝试在本地计算机上扩展通配符“gs://my-bucket/*”,则不匹配任何本地文件,且命令失败)。

    请注意,一些 shell 的通配符字符集中包含其他字符。例如,如果您将 zsh 与启用它的 extendedglob 选项搭配使用,则系统会将“#”视为特殊字符,从而与引用带版本控制的对象时使用的该字符相冲突(请参阅 gsutil 帮助:版本))。

    为避免这些问题,请使用英文单引号(Linux 上)或英文双引号(Windows 上)括住通配符表达式。

  2. 尝试指定包含通配符的文件名时操作无效,这是因为 gsutil 将试着扩展通配符,而不是以字面量字符的形式使用通配符。例如,运行命令:

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

    会导致 gsutil 尝试将“[1]”部分作为通配符进行匹配。

    支持 gsutil 以“原始”模式提供方法处理包含通配符的文件名时,会出现一个公认的问题,直到/除非该支持得到实现,否则使用 gsutil 处理此类文件名没有真正好的方法。您可以使用通配符来命名此类文件,例如将上述命令替换为:

    gsutil cp './file*1*' gs://my-bucket
    

    但这种方法一般可能不好用。

本地文件系统中“Dot”文件的不同行为

根据标准 Unix 行为,通配符“*”仅匹配不以“.”字符开头的文件(以避免与所有 Unix 目录中存在的“.”和“..”目录混淆)。针对文件系统 URI 使用通配符时,gsutil 提供相同的行为,但针对云端 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 个通配符元素);
  • 与每个元素匹配的子目录的数量;以及
  • 结果的数量(每 1000 个结果使用一次 GET 请求实现一次分页,从而为每页指定标记)。

如果要使用路径中间通配符,您可以尝试改用递归通配符,例如:

gsutil ls gs://bucket/**/obj5

它匹配的对象将比“gs://bucket/*/obj5”(因为它跨目录)更多,但会使用分隔符更少的存储分区列出请求(这意味着存储分区请求减少,但它会列出整个存储分区并进行本地过滤,因此可能需要大量的网络流量。)