How to delete files recursively from an S3 bucket

Amazon S3Amazon Web-Services

Amazon S3 Problem Overview


I have the following folder structure in S3. Is there a way to recursively remove all files under a certain folder (say 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 Solutions


Solution 1 - Amazon S3

With the latest aws-cli python command line tools, to recursively delete all the files under a folder in a bucket is just:

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

Or delete everything under the bucket:

aws s3 rm --recursive s3://your_bucket_name

If what you want is to actually delete the bucket, there is one-step shortcut:

aws s3 rb --force s3://your_bucket_name

which will remove the contents in that bucket recursively then delete the bucket.

Note: the s3:// protocol prefix is required for these commands to work

Solution 2 - Amazon S3

This used to require a dedicated API call per key (file), but has been greatly simplified due to the introduction of Amazon S3 - Multi-Object Delete in December 2011:

> Amazon S3's new Multi-Object Delete gives you the ability to > delete up to 1000 objects from an S3 bucket with a single request.

See my answer to the related question delete from S3 using api php using wildcard for more on this and respective examples in PHP (the AWS SDK for PHP supports this since version 1.4.8).

Most AWS client libraries have meanwhile introduced dedicated support for this functionality one way or another, e.g.:

Python

You can achieve this with the excellent boto Python interface to AWS roughly as follows (untested, from the top of my head):

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

This is available since version 1.24 of the AWS SDK for Ruby and the release notes provide an example as well:

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!

Or:

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

Solution 3 - Amazon S3

You might also consider using Amazon S3 Lifecycle to create an expiration for files with the prefix foo/bar1.

Open the S3 browser console and click a bucket. Then click Properties and then LifeCycle.

Create an expiration rule for all files with the prefix foo/bar1 and set the date to 1 day since file was created.

Save and all matching files will be gone within 24 hours.

Just don't forget to remove the rule after you're done!

No API calls, no third party libraries, apps or scripts.

I just deleted several million files this way.

A screenshot showing the Lifecycle Rule window (note in this shot the Prefix has been left blank, affecting all keys in the bucket):

enter image description here

Solution 4 - Amazon S3

The voted up answer is missing a step.

Per aws s3 help:

> Currently, there is no support for the use of UNIX style wildcards in a command's path arguments. However, most commands have --exclude "<value>" and --include "<value>" parameters that can achieve the desired result......... When there are multiple filters, the rule is the filters that appear later in the command take precedence over filters that appear earlier in the command. For example, if the filter parameters passed to the command were --exclude "*" --include "*.txt" All files will be excluded from the command except for files ending with .txt

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

Solution 5 - Amazon S3

With s3cmd package installed on a Linux machine, you can do this

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

Solution 6 - Amazon S3

In case if you want to remove all objects with "foo/" prefix using Java AWS SDK 2.0

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;
};

Solution 7 - Amazon S3

In case using AWS-SKD for 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

attention please, all "foo/*" under bucket will delete.

Solution 8 - Amazon S3

I just removed all files from my bucket by using PowerShell:

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

Solution 9 - Amazon S3

Just saw that Amazon added a "How to Empty a Bucket" option to the AWS console menu:

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

Solution 10 - Amazon S3

Best way is to use lifecycle rule to delete whole bucket contents. Programmatically you can use following code (PHP) to PUT lifecycle rule.

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

In above case all the objects will be deleted starting Date - "Today GMT midnight".

You can also specify Days as follows. But with Days it will wait for at least 24 hrs (1 day is minimum) to start deleting the bucket contents.

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

Solution 11 - Amazon S3

I needed to do the following...

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

Solution 12 - Amazon S3

To delete all the versions of the objects under a specific folder:

Pass the path /folder/subfolder/ to the Prefix -


import boto3

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionpriyaView Question on Stackoverflow
Solution 1 - Amazon S3number5View Answer on Stackoverflow
Solution 2 - Amazon S3Steffen OpelView Answer on Stackoverflow
Solution 3 - Amazon S3RyanView Answer on Stackoverflow
Solution 4 - Amazon S3ecoView Answer on Stackoverflow
Solution 5 - Amazon S3MichaelZView Answer on Stackoverflow
Solution 6 - Amazon S3abguyView Answer on Stackoverflow
Solution 7 - Amazon S3HajimeView Answer on Stackoverflow
Solution 8 - Amazon S3velaskecView Answer on Stackoverflow
Solution 9 - Amazon S3JamesKnView Answer on Stackoverflow
Solution 10 - Amazon S3Shriganesh ShintreView Answer on Stackoverflow
Solution 11 - Amazon S3ImdadView Answer on Stackoverflow
Solution 12 - Amazon S3mellifluousView Answer on Stackoverflow