2014-02-19 83 views
4

比方说,我有不同尺寸的图像对S3:如何删除S3开头的文件

137ff24f-02c9-4656-9d77-5e761d76a273.webp 
137ff24f-02c9-4656-9d77-5e761d76a273_500_300.webp 
137ff24f-02c9-4656-9d77-5e761d76a273_400_280.webp 

我使用博托删除单个文件:

bucket = get_s3_bucket() 
s3_key = Key(bucket) 
s3_key.key = '137ff24f-02c9-4656-9d77-5e761d76a273.webp' 
bucket.delete_key(s3_key) 

但我想删除以137ff24f-02c9-4656-9d77-5e761d76a273开头的所有密钥。

请记住,存储桶中可能有数百个文件,因此我不想遍历所有文件。有没有办法只删除以特定字符串开头的文件?

也许有一些正则表达式的删除功能。

回答

6

的S3服务不支持多删除操作让您删除多达1000个对象在一个单一的API调用。但是,此API调用不提供对密钥的服务器端筛选的支持。您必须提供您要删除的密钥列表。

你可以推出自己的。首先,您需要获取要删除的所有密钥的列表。

import boto 

s3 = boto.connect_s3() 
bucket = s3.get_bucket('mybucket') 
to_delete = list(bucket.list(prefix='137ff24f-02c9-4656-9d77-5e761d76a273')) 

list调用返回一个发电机,但我认为转换使用list如此,to_delete变量现在指向所有在桶符合我所提供的前缀的对象的列表清单。

现在,我们需要从大列表中创建最多1000个对象的块,并使用块来调用存储桶对象的delete_keys方法。

for chunk in [to_delete[i:i+1000] for i in range(0, len(to_delete), 1000)]: 
    result = bucket.delete_keys(chunk) 
    if result.errors: 
     print('The following errors occurred') 
     for error in result.errors: 
      print(error) 

有更有效的方式来做到这一点(例如不斗发电机转换成列表),你可能想处理错误时,做不同的事情,但是这应该给你一个起点。

2

是的。尝试使用s3cmd,S3的命令行工具。首先获取存储桶中所有文件的列表。

cmd = 's3cmd ls s3://bucket_name' 
args = shlex.split(cmd) 
ls_lines = subprocess.check_output(args).splitlines() 

找到所有以你想要的字符串开头的行(使用正则表达式,应该很简单)。使用下面的命令删除所有THRM的:

s3cmd del s3://bucket_name/file_name(s) 

或者,如果你只是想用一个命令:

s3cmd del s3://bucket_name/string* 

我提到的第一种方法,让您可以测试文件要删除的名字并且不要意外删除其他任何东西。

+0

使用asterix(*)的通配符删除绝对有效's3:// bucket-name/string *'!!!!!!!! –

+0

但是看起来's3cmd'会一个接一个地删除文件(在我的情况下,每个文件大约需要0.5秒)。因此,如果您需要非常快速地删除50万个文件,那么您将需要基于多次删除的解决方案。但对于偶尔清理S3桶来说,这种方法看起来非常好 –

1

尽管没有直接的boto方法来做你想做的事情,但你应该可以通过使用get_all_keys来高效地完成它,使用上述正则表达式对它们进行过滤,然后调用delete_keys

这样做,这样将只使用两个请求,做正则表达式的客户端应该是相当快