So rekursiv Dateien aus einem S3-Bucket löschen

86

Ich habe die folgende Ordnerstruktur in S3. Gibt es eine Möglichkeit, alle Dateien unter einem bestimmten Ordner rekursiv zu entfernen (z foo/bar1 or foo or foo/bar2/1. B. ..)

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

foo/bar2/1/..
foo/bar2/2/..
foo/bar2/3/..
Priya
quelle

Antworten:

160

Mit den neuesten aws-cli-Python-Befehlszeilentools können Sie rekursiv alle Dateien unter einem Ordner in einem Bucket löschen:

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

Oder löschen Sie alles unter dem Eimer:

aws s3 rm --recursive s3://your_bucket_name

Wenn Sie den Bucket tatsächlich löschen möchten, gibt es eine einstufige Verknüpfung:

aws s3 rb --force s3://your_bucket_name

Dadurch wird der Inhalt in diesem Bucket rekursiv entfernt und der Bucket gelöscht.

Hinweis: Damit s3://diese Befehle funktionieren, ist das Protokollpräfix erforderlich

Nummer 5
quelle
2
Das sollte die Antwort sein. Es ist ein (neues), leistungsstarkes Standardwerkzeug, das für Dinge wie diese Frage entwickelt wurde
Don Cheadle
Dies löscht die Dateien einwandfrei, löscht aber auch den Bucket nach dem Löschen der Dateien. Habe ich etwas vergessen?
Naveen
@Naveen, wie ich oben sagte, rmlöscht nur Dateien, aber rb --forcedie Dateien und den Bucket.
Nummer 5
4
using --recursivelöscht auch den Ordner.
Ryantuck
1
@ Moseleyi Ich glaube, dass Sie nicht wirklich einen leeren Ordner in einem S3-Bucket haben können
Ryantuck
58

Dies erforderte früher einen dedizierten API-Aufruf pro Schlüssel (Datei), wurde jedoch durch die Einführung von Amazon S3 - Multi-Object Delete im Dezember 2011 erheblich vereinfacht :

Mit dem neuen Multi-Object Delete von Amazon S3 können Sie mit einer einzigen Anforderung bis zu 1000 Objekte aus einem S3-Bucket löschen.

Weitere Informationen zu diesem und den entsprechenden Beispielen in PHP finden Sie in meiner Antwort auf die entsprechende Frage zum Löschen aus S3 mithilfe von API PHP mithilfe von Platzhaltern (das AWS SDK für PHP unterstützt dies seit Version 1.4.8 ).

Die meisten AWS-Client-Bibliotheken haben inzwischen auf die eine oder andere Weise eine spezielle Unterstützung für diese Funktionalität eingeführt, z.

Python

Sie können dies mit der hervorragenden Boto- Python-Schnittstelle zu AWS ungefähr wie folgt erreichen (ungetestet, von oben):

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])

Rubin

Dies ist seit Version 1.24 des AWS SDK für Ruby verfügbar. Die Versionshinweise enthalten ebenfalls ein Beispiel:

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!

Oder:

AWS::S3::Bucket.delete('your_bucket', :force => true)
Steffen Opel
quelle
sollte die neue aws cliAntwort von like @ number5 unter docs.aws.amazon.com/cli/latest/reference/s3/rm.html
Don Cheadle
43

Sie können auch Amazon S3 Lifecycle verwenden, um einen Ablauf für Dateien mit dem Präfix zu erstellen foo/bar1.

Öffnen Sie die S3-Browserkonsole und klicken Sie auf einen Bucket. Klicken Sie dann auf Eigenschaften und dann auf Lebenszyklus.

Erstellen Sie eine Ablaufregel für alle Dateien mit dem Präfix foo/bar1und setzen Sie das Datum auf 1 Tag seit der Erstellung der Datei.

Speichern und alle übereinstimmenden Dateien werden innerhalb von 24 Stunden gelöscht.

Vergiss nur nicht, die Regel zu entfernen, wenn du fertig bist!

Keine API-Aufrufe, keine Bibliotheken, Apps oder Skripte von Drittanbietern.

Ich habe gerade mehrere Millionen Dateien auf diese Weise gelöscht.

Ein Screenshot mit dem Fenster "Lebenszyklusregel" (Beachten Sie, dass in dieser Aufnahme das Präfix leer gelassen wurde, was sich auf alle Schlüssel im Bucket auswirkt):

Geben Sie hier die Bildbeschreibung ein

Ryan
quelle
4
Tolle Idee für die Verwendung von Lifecycle anstelle eines Löschbefehls.
xis
Lassen Sie S3 genau das für Sie tun.
Ryan
Sie können dies auch auf den gesamten Bucket anwenden, um den Bucket zu löschen.
Indolering
7

Für den Fall, dass Sie alle Objekte mit dem Präfix "foo /" mit Java AWS SDK 2.0 entfernen möchten

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;
};
abguy
quelle
1
Ich kann keine aussagekräftigere Demonstration dafür finden, was die Leute an Java nicht mögen als diese Antwort ...
Jivan
5

Wenn das s3cmdPaket auf einem Linux-Computer installiert ist, können Sie dies tun

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

MichaelZ
quelle
1
Laut der Hilfe handelt es sich entweder um das Löschen einzelner Objekte s3cmd del s3://BUCKET/OBJECToder um das Löschen des gesamten Buckets s3cmd rb s3://BUCKET. s3cmd rmZumindest nach gibt es keine s3cmd --help.
Paul McMurdie
s3cmd rmist in der Hilfe ab 2019 (als Alias ​​für del), dies ist eine hervorragende Antwort. Die awscli-Tools arbeiten nur mit einem /abschließenden Präfix, nicht jedoch mit einem Ordner- und einem partiellen Dateinamenpräfix, während s3cmd in beiden Fällen funktioniert. Diese Antwort erfordert viel mehr Upvotes. Ich musste viel zu weit scrollen, um die richtige Lösung zu finden.
David Parks
3

Bei Verwendung von AWS-SKD für 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

Achtung bitte, alle "foo / *" unter Bucket werden gelöscht.

Hajime
quelle
2

Ich habe gerade alle Dateien mit PowerShell aus meinem Bucket entfernt:

Get-S3Object -BucketName YOUR_BUCKET | % { Remove-S3Object -BucketName YOUR_BUCKET -Key $_.Key -Force:$true }
velaskec
quelle
Vielen Dank, dass Sie diese Antwort gepostet haben. Ich habe versucht, genau das zu tun, und -Key "% _. Key" eingegeben, was nicht funktioniert.
Scott Gartner
1

Der abgestimmten Antwort fehlt ein Schritt.

Per aws s3 Hilfe:

Derzeit wird die Verwendung von Platzhaltern im UNIX-Stil in den Pfadargumenten eines Befehls nicht unterstützt. Allerdings ist die meisten Befehle haben --exclude "<value>"und --include "<value>" Parameter , die das gewünschte Ergebnis erzielen können ......... Wenn mehrere Filter sind, sind die Regel , die Filter , die später in dem Befehl hat Vorrang vor Filter angezeigt , die zuvor in dem Befehl angezeigt. Wenn beispielsweise die an den Befehl übergebenen Filterparameter --exclude "*" --include "*.txt"Alle Dateien mit Ausnahme von Dateien, die mit .txt enden, vom Befehl ausgeschlossen werden

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

Der beste Weg ist, die Lebenszyklusregel zu verwenden, um den gesamten Inhalt des Buckets zu löschen. Programmatisch können Sie folgenden Code (PHP) verwenden, um die Lebenszyklusregel zu PUTEN.

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

Im obigen Fall werden alle Objekte ab dem Datum "Heute GMT Mitternacht" gelöscht.

Sie können Tage auch wie folgt angeben. Bei Tagen dauert es jedoch mindestens 24 Stunden (mindestens 1 Tag), bis der Inhalt des Eimers gelöscht ist.

$expiration = array('Days' => 1);
Shriganesh Shintre
quelle
0

Ich musste folgendes tun ...

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
Imdad
quelle