在 boto3 中过滤类似 glob 的正则表达式模式

filter a glob-like regex pattern in boto3

我可以使用 boto3 的过滤工具在存储桶中查找键(技术上是子键),类似于使用 glob 目录中的文件吗?

我想获得一个键列表,其模式类似于 "key/**/<pattern>/**.gz"

不幸的是没有。 S3 不提供对结果过滤的服务器端支持(前缀和定界符除外)。

您可以通过 (ab) 使用分页器并使用 .gz 作为分隔符来做到这一点。 Paginator 将 return 键的通用前缀(在这种情况下,包括 .gz 文件扩展名在内的所有内容,不包括存储桶名称,即整个键),您可以对这些字符串进行一些正则表达式比较。

我不是在猜测你的 <pattern> 是什么,我提供的正则表达式有点粗糙,但基本上你想要的是这个。

import boto3
import re

region = 'ap-southeast-2' ## <- YOUR REGION HERE
s3client = boto3.client('s3', region_name=region)

paginator = s3client.get_paginator('list_objects')

source_bucket = 'MY-BUCKET-NAME'
source_prefix = 'OPTIONAL-PREFIX/NESTED/'

pat = re.compile(r'key\/.+\/<pattern>\/.+.gz')

for result in paginator.paginate(Bucket=source_bucket, Prefix=source_prefix, Delimiter='.gz'):
    for prefixes in result.get('CommonPrefixes'):
        commonprefix = prefixes.get('Prefix')
        key_path = commonprefix.split('/')
        m = re.search(pat, key_path[2])
        if m is not None:
            print(commonprefix)

您可以使用 exrex 库根据正则表达式生成所有字符串并将其传递给 boto3。这是一个简单的例子,但你可以想象一些更复杂的东西:

例如:

import exrex
import boto3
session = boto3.Session() # profile_name='xyz'
s3 = session.resource('s3')
bucket = s3.Bucket('mybucketname')

prefixes = list(exrex.generate(r'api/v2/responses/2016-11-08/(2016-11-08T2[2-3]|2016-11-09)'))

objects = []
for prefix in prefixes:
    print(prefix, end=" ")
    current_objects = list(bucket.objects.filter(Prefix=prefix))
    print(len(current_objects))
    objects += current_objects

这给出了输出:

api/v2/responses/2016-11-08/2016-11-08T22 1056
api/v2/responses/2016-11-08/2016-11-08T23 1056
api/v2/responses/2016-11-08/2016-11-09 24677