Come eliminare i file in modo ricorsivo da un bucket S3


90

Ho la seguente struttura di cartelle in S3. C'è un modo per rimuovere in modo ricorsivo tutti i file in una determinata cartella (ad esempio 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/..

Risposte:


169

Con gli ultimi strumenti a riga di comando di aws-cli python , eliminare in modo ricorsivo tutti i file in una cartella in un bucket è solo:

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

Oppure elimina tutto sotto il secchio:

aws s3 rm --recursive s3://your_bucket_name

Se quello che vuoi è effettivamente eliminare il bucket, c'è una scorciatoia in un passaggio:

aws s3 rb --force s3://your_bucket_name

che rimuoverà i contenuti in quel bucket in modo ricorsivo, quindi eliminerà il bucket.

Nota: il s3://prefisso del protocollo è necessario affinché questi comandi funzionino


2
questa dovrebbe essere la risposta. È uno strumento potente e standard (nuovo), progettato per cose come questa domanda
Don Cheadle

Questo sta eliminando i file senza problemi, ma sta anche eliminando il bucket dopo aver eliminato i file. Mi sono perso qualcosa?
Naveen

1
@Naveen come ho detto sopra, rmeliminerà solo i file ma rb --forceeliminerà i file e il bucket.
numero

5
utilizzando --recursiveelimina anche la cartella.
ryantuck

2
@Moseleyi, credo che non si possa effettivamente avere una cartella vuota in un bucket S3
ryantuck

58

Ciò richiedeva una chiamata API dedicata per chiave (file), ma è stata notevolmente semplificata grazie all'introduzione di Amazon S3 - Multi-Object Delete nel dicembre 2011:

Il nuovo Multi-Object Delete di Amazon S3 ti dà la possibilità di eliminare fino a 1000 oggetti da un bucket S3 con una singola richiesta.

Per ulteriori informazioni su questo e sui rispettivi esempi in PHP, vedere la mia risposta alla domanda correlata Elimina da S3 utilizzando api php utilizzando caratteri jolly (l' SDK AWS per PHP lo supporta dalla versione 1.4.8 ).

La maggior parte delle librerie client AWS ha nel frattempo introdotto il supporto dedicato per questa funzionalità in un modo o nell'altro, ad esempio:

Pitone

Puoi ottenere ciò con l'eccellente interfaccia boto Python per AWS più o meno come segue (non testato, dalla parte superiore della mia testa):

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

Rubino

Questo è disponibile in quanto la versione 1.24 del AWS SDK per Ruby e le note di rilascio forniscono un esempio così:

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!

O:

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

dovrebbe usare la nuova aws clirisposta come @ numero5 sotto docs.aws.amazon.com/cli/latest/reference/s3/rm.html
Don Cheadle

43

Potresti anche considerare di utilizzare Amazon S3 Lifecycle per creare una scadenza per i file con il prefisso foo/bar1.

Apri la console del browser S3 e fai clic su un bucket. Quindi fare clic su Proprietà e quindi su Ciclo di vita.

Crea una regola di scadenza per tutti i file con il prefisso foo/bar1e imposta la data su 1 giorno dalla creazione del file.

Salva e tutti i file corrispondenti spariranno entro 24 ore.

Non dimenticare di rimuovere la regola dopo aver finito!

Nessuna chiamata API, nessuna libreria, app o script di terze parti.

Ho appena cancellato diversi milioni di file in questo modo.

Uno screenshot che mostra la finestra Regola del ciclo di vita (nota in questa ripresa il prefisso è stato lasciato vuoto, interessando tutte le chiavi nel bucket):

inserisci qui la descrizione dell'immagine


4
Ottima idea per utilizzare Lifecycle invece di qualche comando di cancellazione.
xis

Esatto, lascia che S3 lo faccia per te.
Ryan

Puoi anche applicarlo all'intero bucket, consentendoti di eliminare il bucket.
Indolenza

8

Con il s3cmdpacchetto installato su una macchina Linux, puoi farlo

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


1
A seconda dell'aiuto, è possibile eliminare un singolo oggetto s3cmd del s3://BUCKET/OBJECTo eliminare l' intero bucket s3cmd rb s3://BUCKET. Non c'è s3cmd rm, almeno secondo s3cmd --help.
Paul McMurdie

s3cmd rmè in aiuto dal 2019 (come alias per del), questa è un'ottima risposta. Gli awsstrumenti cli funzionano solo contro un /prefisso di terminazione, ma non una cartella e un prefisso di nome file parziale, mentre s3cmd funziona in entrambi i casi. Questa risposta richiede molti più voti positivi, ho dovuto scorrere troppo lontano per trovare la soluzione giusta.
David Parks,

8

Nel caso in cui desideri rimuovere tutti gli oggetti con il prefisso "foo /" utilizzando 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;
};

1
Non riesco a trovare una dimostrazione più significativa di ciò che alla gente non piace di Java di questa risposta ...
Jivan

3

Nel caso in cui si utilizzi AWS-SKD per 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

attenzione per favore, tutti i "foo / *" sotto il bucket verranno eliminati.


2

Ho appena rimosso tutti i file dal mio bucket utilizzando PowerShell:

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

Grazie per aver postato questa risposta, stavo cercando di fare esattamente questa cosa e avevo messo -Key "% _. Key" che non funziona.
Scott Gartner


2

La risposta votata manca un passaggio.

Per aws s3 aiuto:

Attualmente, non esiste alcun supporto per l'uso di caratteri jolly in stile UNIX negli argomenti del percorso di un comando. Tuttavia, la maggior parte dei comandi hanno --exclude "<value>"e --include "<value>" parametri che possono ottenere il risultato desiderato ......... Quando ci sono più filtri, la regola è i filtri che compaiono successivamente nel comando hanno la precedenza su filtri che appaiono in precedenza nel comando. Ad esempio, se i parametri del filtro passati al comando erano --exclude "*" --include "*.txt"Tutti i file verranno esclusi dal comando ad eccezione dei file che terminano con .txt

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

0

Il modo migliore è utilizzare la regola del ciclo di vita per eliminare l'intero contenuto del bucket. A livello di codice è possibile utilizzare il seguente codice (PHP) per inserire la regola del ciclo di vita.

$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 questo caso tutti gli oggetti verranno cancellati. Data di inizio - "Oggi GMT mezzanotte".

È inoltre possibile specificare i giorni come segue. Ma con Days aspetterà almeno 24 ore (1 giorno è minimo) per iniziare a eliminare il contenuto del bucket.

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

0

Avevo bisogno di fare quanto segue ...

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.