如何从S3存储桶中递归删除文件


87

我在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/..

Answers:


163

使用最新的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://这些命令必须使用协议前缀


2
这应该是答案。这是一个(新-ISH)标准的,功能强大的工具,设计的东西就像这个问题
唐·钱德尔

这样可以删除文件,但是删除文件后也可以删除存储桶。我想念什么吗?
Naveen 2015年

1
我上面说的@Naveenrm只会删除文件,但rb --force会删除文件存储桶。
6

5
使用--recursive也会删除该文件夹。
ryantuck '16

1
@Moseleyi我相信您实际上不能在S3存储桶中有一个空文件夹
ryantuck

58

过去,每个密钥(文件)都需要专用的API调用,但是由于2011年12月推出了Amazon S3-多对象删除,因此大大简化了操作:

Amazon S3的新“多对象删除”使您能够通过一个请求从S3存储桶中删除多达1000个对象。

请参阅我对使用api php使用通配符从S3删除相关问题的答案,以获取有关此示例以及PHP中各个示例的更多信息(适用于PHP的AWS开发工具包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])

红宝石

这是可用的,因为适用于RubyAWS开发工具包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)

应该在aws clidocs.aws.amazon.com/cli/latest/reference/s3/rm.html下面使用新的类似@ number5的答案
Don Cheadle

43

您可能还会考虑使用Amazon S3 Lifecycle为带有前缀的文件创建到期时间foo/bar1

打开S3浏览器控制台,然后单击存储桶。然后单击属性,然后单击LifeCycle。

为所有带有前缀的文件创建过期规则,foo/bar1并将日期设置为自文件创建以来的1天。

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

只是不要忘记在完成后删除规则!

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

我只是以这种方式删除了数百万个文件。

屏幕快照显示了“生命周期规则”窗口(在此快照中,“前缀”留为空白,影响存储桶中的所有键):

在此处输入图片说明


4
使用Lifecycle而不是某些delete命令的好主意。
xis 2014年

确实,让S3为您做。
瑞安

您也可以将其应用于整个存储桶,从而删除存储桶。
Indolering 2014年

8

如果要使用Java AWS开发工具包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;
};

1
除了这个答案,我找不到其他人更喜欢Java的说明了……
Jivan

7

s3cmdLinux机器上安装软件包后,您可以执行此操作

s3cmd rm s3://foo/bar --recursive


1
根据帮助,它可以是单对象删除s3cmd del s3://BUCKET/OBJECT或整个存储桶删除s3cmd rb s3://BUCKET。没有s3cmd rm,至少根据s3cmd --help
Paul McMurdie

s3cmd rm在2019年有帮助(del的别名),这是一个很好的答案。该awsCLI工具只能针对一个工作/终端的前缀,而不是一个文件夹和部分文件名前缀,而在这两种情况下s3cmd作品。这个答案需要更多的支持,我不得不滚动太远才能找到正确的解决方案。
David Parks

3

如果将AWS-SKD用于ruby V2。

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 / *”都将删除。


2

我刚刚使用PowerShell从存储桶中删除了所有文件:

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

感谢您发布此答案,我正试图做这件事,并已将-Key“%_。Key”放了,但不起作用。
Scott Gartner


1

投票表决的答案缺少一步。

Per AWS S3帮助:

当前,在命令的路径参数中不支持使用UNIX样式通配符。但是,大多数命令的 --exclude "<value>"--include "<value>" 参数都可以达到预期的结果......当有多个过滤器时,规则是命令后面出现的过滤器优先于命令前面出现的过滤器。例如,如果传递给命令的过滤器参数为“ --exclude "*" --include "*.txt".txt结尾”,则所有文件都将从命令中排除。

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

0

最好的方法是使用生命周期规则删除整个存储桶内容。您可以通过编程使用以下代码(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天)才能开始删除存储桶内容。

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

0

我需要做以下事情...

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.