【问题标题】:How to delete files recursively from an S3 bucket如何从 S3 存储桶中递归删除文件
【发布时间】:2012-04-20 18:00:31
【问题描述】:

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

【问题讨论】:

    标签: amazon-s3 amazon-web-services


    【解决方案1】:

    使用最新的aws-cli python command line tools,递归删除bucket中某个文件夹下的所有文件即可:

    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:// 协议前缀才能工作

    【讨论】:

    • 这应该是答案。这是一个(新的)标准、强大的工具,专为像这个问题这样的事情而设计
    • @Naveen 正如我上面所说,rm 只会删除文件,但rb --force 会删除文件存储桶。
    • 使用--recursive 也会删除该文件夹。
    • @RyanTuck 你知道如何阻止它删除文件夹吗?
    • @Moseleyi 我相信您实际上不能在 s3 存储桶中拥有一个空文件夹
    【解决方案2】:

    这过去需要对每个密钥(文件)进行专门的 API 调用,但由于在 2011 年 12 月引入了Amazon S3 - Multi-Object Delete,这已大大简化:

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

    请参阅我对相关问题 delete from S3 using api php using wildcard 的回答,了解有关此问题和 PHP 中相应示例的更多信息(AWS SDK for PHP 支持这一点,因为 version 1.4.8)。

    大多数 AWS 客户端库同时以一种或另一种方式引入了对此功能的专门支持,例如:

    Python

    您可以使用与 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])
    

    红宝石

    这从version 1.24AWS SDK for Ruby 开始可用,并且发行说明也提供了一个示例:

    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)
    

    【讨论】:

    【解决方案3】:

    您也可以考虑使用 Amazon S3 生命周期为前缀为 foo/bar1 的文件创建过期时间。

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

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

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

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

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

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

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

    【讨论】:

    • 使用生命周期代替删除命令的好主意。
    • 没错,让S3为你做。
    • 您也可以将其应用于整个存储桶,从而使您能够删除存储桶。
    【解决方案4】:

    在 Linux 机器上安装 s3cmd 包后,您可以这样做

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

    【讨论】:

    • 根据帮助,要么是单对象删除s3cmd del s3://BUCKET/OBJECT,要么是整个桶删除s3cmd rb s3://BUCKET。没有s3cmd rm,至少按照s3cmd --help.
    • s3cmd rm 自 2019 年起在帮助中(作为 del 的别名),这是一个很好的答案。 aws cli 工具仅适用于 / 终止前缀,而不适用于文件夹和部分文件名前缀,而 s3cmd 在这两种情况下都适用。这个答案需要更多的支持,我不得不滚动太远才能找到正确的解决方案。
    【解决方案5】:

    如果您想使用 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;
    };
    

    【讨论】:

    • 我找不到比这个答案更能说明人们不喜欢 Java 的地方了...
    【解决方案6】:

    投票的答案缺少一步。

    根据 aws s3 帮助:

    目前,不支持在 a 中使用 UNIX 样式的通配符 命令的路径参数。但是,大多数命令都有--exclude "&lt;value&gt;"--include "&lt;value&gt;"参数,可以实现 期望的结果............当有多个 过滤器,规则是稍后出现在命令中的过滤器 优先于命令中较早出现的过滤器。例如,如果传递给命令的过滤器参数是--exclude "*"--include "*.txt",所有文件都将被排除在命令之外,除了文件结尾 带有.txt

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

    【讨论】:

      【解决方案7】:

      如果将 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
      

      请注意,bucket下的所有“foo/*”都会被删除。

      【讨论】:

        【解决方案8】:

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

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

        【讨论】:

        • 感谢您发布此答案,我正试图做这件事,但放了 -Key "%_.Key" 不起作用。
        【解决方案9】:

        刚刚看到亚马逊在 AWS 控制台菜单中添加了“如何清空存储桶”选项:

        http://docs.aws.amazon.com/AmazonS3/latest/UG/DeletingaBucket.html

        【讨论】:

          【解决方案10】:

          最好的方法是使用生命周期规则来删除整个存储桶内容。以编程方式,您可以使用以下代码 (PHP) 来 PUT 生命周期规则。

          $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);
          

          【讨论】:

            【解决方案11】:

            我需要执行以下操作...

            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
            

            【讨论】:

              【解决方案12】:

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

              将路径/folder/subfolder/ 传递给前缀-

              
              import boto3
              
              s3 = boto3.resource('s3')
              bucket = s3.Bucket("my-bucket-name")
              bucket.object_versions.filter(Prefix="foo/bar1/1/").delete()
              

              【讨论】:

                猜你喜欢
                • 2018-05-16
                • 1970-01-01
                • 2011-03-09
                • 1970-01-01
                • 1970-01-01
                • 2015-06-23
                • 2017-02-01
                • 1970-01-01
                • 2012-05-16
                相关资源
                最近更新 更多