如何从 S3桶递归删除文件

我在 S3中有以下文件夹结构。是否有一种方法可以递归地删除某个文件夹下的所有文件(例如 foo/bar1 or foo or foo/bar2/1。.)

foo/bar1/1/..
foo/bar1/2/..
foo/bar1/3/..


foo/bar2/1/..
foo/bar2/2/..
foo/bar2/3/..
177054 次浏览

过去,这需要对每个密钥(文件)进行专门的 API 调用,但是由于2011年12月引入了 Amazon S3-多对象删除,这个过程大大简化了:

Amazon S3的 新的多对象删除功能使您能够 通过一个请求从 S3 bucket 中删除多达1000个对象。

请参阅我对相关问题 使用通配符从 S3中删除的回答,以获得更多关于这方面的信息以及 PHP 中各自的例子(用于 PHP 的 AWS SDK版本1.4.8开始就支持这一点)。

与此同时,大多数 AWS 客户端库都以这样或那样的方式引入了对此功能的专用支持,例如:

巨蟒

您可以通过与 AWS 的优秀 Boto Python 接口来实现这一点,大致如下(未经测试,从头开始) :

import boto
s3 = boto.connect_s3()
bucket = s3.get_bucket("bucketname")
bucketListResultSet = bucket.list(prefix="foo/bar")
result = bucket.delete_keys([key.name for key in bucketListResultSet])

露比

这是可用的,因为 用于 Ruby 的 AWS SDK版本1.24和发行说明也提供了一个例子:

bucket = AWS::S3.new.buckets['mybucket']


# delete a list of objects by keys, objects are deleted in batches of 1k per
# request.  Accepts strings, AWS::S3::S3Object, AWS::S3::ObectVersion and
# hashes with :key and :version_id
bucket.objects.delete('key1', 'key2', 'key3', ...)


# delete all of the objects in a bucket (optionally with a common prefix as shown)
bucket.objects.with_prefix('2009/').delete_all


# conditional delete, loads and deletes objects in batches of 1k, only
# deleting those that return true from the block
bucket.objects.delete_if{|object| object.key =~ /\.pdf$/ }


# empty the bucket and then delete the bucket, objects are deleted in batches of 1k
bucket.delete!

或者:

AWS::S3::Bucket.delete('your_bucket', :force => true)

您还可以考虑使用 AmazonS3LifCycle 为前缀为 foo/bar1的文件创建过期时间。

打开 S3浏览器控制台,单击一个桶,然后单击“属性”,然后单击“生命周期”。

为所有前缀为 foo/bar1的文件创建一个过期规则,并将创建文件后的日期设置为1天。

保存,所有匹配的文件将在24小时内消失。

做完之后别忘了把规则去掉!

没有 API 调用,没有第三方库,应用程序或脚本。

我用这种方法删除了几百万个文件。

一个显示生命周期规则窗口的截图(注意在这个截图中,前缀被留空,影响桶中的所有键) :

enter image description here

使用最新的 Aws-cli python 命令行工具,递归删除桶中一个文件夹下的所有文件就是:

aws s3 rm --recursive s3://your_bucket_name/foo/

或者把桶底下的东西都删掉:

aws s3 rm --recursive s3://your_bucket_name

如果你真的想删除这个桶,有一个简单的方法:

aws s3 rb --force s3://your_bucket_name

它将递归地删除桶中的内容,然后删除桶。

注意: 这些命令的工作需要 s3://协议前缀

我刚刚使用 PowerShell 从 bucket 中删除了所有文件:

Get-S3Object -BucketName YOUR_BUCKET | % { Remove-S3Object -BucketName YOUR_BUCKET -Key $_.Key -Force:$true }

最好的方法是使用生命周期规则删除整个 bucket 内容。通过编程,您可以使用以下代码(PHP)来输入生命周期规则。

$expiration = array('Date' => date('U', strtotime('GMT midnight')));
$result = $s3->putBucketLifecycle(array(
'Bucket' => 'bucket-name',
'Rules' => array(
array(
'Expiration' => $expiration,
'ID' => 'rule-name',
'Prefix' => '',
'Status' => 'Enabled',
),
),
));

在上述情况下,所有对象将被删除开始日期-“今天格林威治标准时间午夜”。

还可以按照以下方式指定天数。但是对于 Days,它至少要等待24小时(最少1天)才能开始删除 bucket 内容。

$expiration = array('Days' => 1);

通过在 Linux 机器上安装 s3cmd包,您可以做到这一点

S3cmd rm s3://foo/bar ——递归

刚刚看到 Amazon 在 AWS 控制台菜单中添加了一个“如何清空桶”选项:

Http://docs.aws.amazon.com/amazons3/latest/ug/deletingabucket.html

我需要做以下几件事。

def delete_bucket
s3 = init_amazon_s3
s3.buckets['BUCKET-NAME'].objects.each do |obj|
obj.delete
end
end


def init_amazon_s3
config = YAML.load_file("#{Rails.root}/config/s3.yml")
AWS.config(:access_key_id => config['access_key_id'],:secret_access_key => config['secret_access_key'])
s3 = AWS::S3.new
end

以防在 Ruby V2中使用 AWS-SKD。

s3.list_objects(bucket: bucket_name, prefix: "foo/").contents.each do |obj|
next if obj.key == "foo/"
resp = s3.delete_object({
bucket: bucket_name,
key: obj.key,
})
end

请注意,桶下所有“ foo/*”将被删除。

如果您想使用 Java AWS SDK 2.0删除所有前缀为“ foo/”的对象,请使用

import java.util.ArrayList;
import java.util.Iterator;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.*;


//...


ListObjectsRequest listObjectsRequest = ListObjectsRequest.builder()
.bucket(bucketName)
.prefix("foo/")
.build()
;
ListObjectsResponse objectsResponse = s3Client.listObjects(listObjectsRequest);


while (true) {
ArrayList<ObjectIdentifier> objects = new ArrayList<>();


for (Iterator<?> iterator = objectsResponse.contents().iterator(); iterator.hasNext(); ) {
S3Object s3Object = (S3Object)iterator.next();
objects.add(
ObjectIdentifier.builder()
.key(s3Object.key())
.build()
);
}


s3Client.deleteObjects(
DeleteObjectsRequest.builder()
.bucket(bucketName)
.delete(
Delete.builder()
.objects(objects)
.build()
)
.build()
);


if (objectsResponse.isTruncated()) {
objectsResponse = s3Client.listObjects(listObjectsRequest);
continue;
}


break;
};

投票选出的答案漏掉了一步。

根据法律第三条的规定:

中使用 UNIX 样式的通配符 命令的路径参数。但是,大多数命令都有 --exclude "<value>"--include "<value>"参数,可以实现 期望的结果。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。 过滤器,规则是稍后出现在命令 take 中的过滤器 优先于命令中早期显示的筛选器。例如,如果传递给命令的筛选器参数为 --exclude "*" --include "*.txt",则除了结束的文件之外,所有文件都将被排除在命令之外 用. txt

aws s3 rm --recursive s3://bucket/ --exclude="*" --include="/folder_path/*"

删除特定文件夹下对象的所有版本:

传递路径 /folder/subfolder/到前缀-


import boto3


s3 = boto3.resource('s3')
bucket = s3.Bucket("my-bucket-name")
bucket.object_versions.filter(Prefix="foo/bar1/1/").delete()
s3cmd del --recursive s3://your_bucket --force