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

pri*_*iya 76 amazon-s3 amazon-web-services

我在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/..
Run Code Online (Sandbox Code Playgroud)

num*_*er5 138

使用最新的aws-cli python命令行工具,以递归方式删除存储桶中文件夹下的所有文件只是:

aws s3 rm --recursive s3://your_bucket_name/foo/
Run Code Online (Sandbox Code Playgroud)

或删除存储桶下的所有内容:

aws s3 rm --recursive s3://your_bucket_name
Run Code Online (Sandbox Code Playgroud)

如果您想要实际删除存储桶,则有一步快捷方式:

aws s3 rb --force s3://your_bucket_name
Run Code Online (Sandbox Code Playgroud)

这将以递归方式删除该存储桶中的内容,然后删除存储桶.

注意:s3://这些命令必须使用协议前缀才能工作

  • 使用`--recursive`也会删除文件夹. (4认同)
  • 这不适用于版本控制下的存储桶. (3认同)
  • 这应该是答案.它是一个(新的)标准,强大的工具,专为像这个问题的东西设计 (2认同)
  • @RyanTuck 你知道如何阻止它删除文件夹吗? (2认同)
  • @Moseleyi 我相信你实际上不能在 s3 存储桶中有一个空文件夹 (2认同)

Ste*_*pel 56

这通常需要为每个密钥(文件)提供专用的API调用,但由于在2011年12月引入了Amazon S3 - 多对象删除,因此大大简化了:

Amazon S3的新多对象删除功能使您能够通过单个请求从S3存储桶中删除多达1000个对象.

请参阅我使用api php使用通配符从S3中删除相关问题的答案,以获取更多信息以及PHP中的相应示例(自1.4.8版以来,AWS SDK for PHP支持此功能).

大多数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])
Run Code Online (Sandbox Code Playgroud)

红宝石

这是从适用于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!
Run Code Online (Sandbox Code Playgroud)

要么:

AWS::S3::Bucket.delete('your_bucket', :force => true)
Run Code Online (Sandbox Code Playgroud)


Rya*_*yan 41

您还可以考虑使用Amazon S3 Lifecycle为具有前缀的文件创建过期foo/bar1.

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

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

保存并且所有匹配的文件将在24小时内消失.

完成后别忘了删除规则!

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

我刚用这种方式删除了几百万个文件.

显示生命周期规则窗口的屏幕截图(在此镜头中注意,前缀已留空,影响存储桶中的所有键):

在此输入图像描述

  • 使用Lifecycle而不是一些删除命令的好主意. (4认同)

Mic*_*elZ 10

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

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

  • 根据帮助,它是单个对象删除 `s3cmd del s3://BUCKET/OBJECT` 或整个存储桶删除 `s3cmd rb s3://BUCKET`。至少根据“s3cmd --help”,没有“s3cmd rm”。 (2认同)
  • 自 2019 年起,“s3cmd rm”已在帮助中(作为 del 的别名),这是一个很好的答案。`aws` cli 工具仅适用于 `/` 终止前缀,但不适用于文件夹和部分文件名前缀,而 s3cmd 在这两种情况下都适用。这个答案需要更多的赞成票,我不得不滚动太远才能找到正确的解决方案。 (2认同)

ein*_*arc 8

投票赞成的答案缺少一步。

根据 aws s3 帮助:

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

aws s3 rm --recursive s3://bucket/ --exclude="*" --include="/folder_path/*" 
Run Code Online (Sandbox Code Playgroud)


abg*_*guy 6

如果要使用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;
};
Run Code Online (Sandbox Code Playgroud)

  • 我找不到比这个答案更能说明人们不喜欢 Java 的地方了…… (2认同)