Jak rekurencyjnie usuwać pliki z zasobnika S3


90

Mam następującą strukturę folderów w S3. Czy istnieje sposób na rekurencyjne usuwanie wszystkich plików w określonym folderze (powiedzmy 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/..

Odpowiedzi:


169

Dzięki najnowszym narzędziom wiersza poleceń aws-cli python rekurencyjne usuwanie wszystkich plików w folderze w wiadrze jest po prostu:

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

Lub usuń wszystko, co znajduje się pod wiadrem:

aws s3 rm --recursive s3://your_bucket_name

Jeśli chcesz faktycznie usunąć zasobnik, istnieje jednoetapowy skrót:

aws s3 rb --force s3://your_bucket_name

co spowoduje rekurencyjne usunięcie zawartości tego zasobnika, a następnie usunie zasobnik.

Uwaga: s3://do działania tych poleceń wymagany jest przedrostek protokołu


2
to powinna być odpowiedź. To (nowy) standardowe, potężne narzędzie, zaprojektowane z myślą o takich rzeczach jak to pytanie
Don Cheadle,

To jest dobre usunięcie plików, ale także usunięcie zasobnika po usunięciu plików. Czy coś przegapiłem?
Naveen

1
@Naveen, jak powiedziałem powyżej, rmusunie tylko pliki, ale rb --forceusunie pliki i zasobnik.
numer5

5
użycie --recursivepowoduje również usunięcie folderu.
ryantuck

2
@Moseleyi Wierzę, że nie możesz mieć pustego folderu w wiadrze
S3

58

Kiedyś wymagało to dedykowanego wywołania API dla każdego klucza (pliku), ale zostało znacznie uproszczone ze względu na wprowadzenie Amazon S3 - Multi-Object Delete w grudniu 2011:

Nowa funkcja usuwania wielu obiektów Amazon S3 umożliwia usunięcie do 1000 obiektów z zasobnika S3 za pomocą jednego żądania.

Zobacz moją odpowiedź na powiązane pytanie, usuń z S3 używając api php z użyciem symboli wieloznacznych, aby uzyskać więcej informacji na temat tego i odpowiednich przykładów w PHP ( AWS SDK dla PHP obsługuje to od wersji 1.4.8 ).

Większość bibliotek klienta AWS w międzyczasie wprowadziła dedykowane wsparcie dla tej funkcji w taki czy inny sposób, np .:

Pyton

Możesz to osiągnąć dzięki doskonałemu interfejsowi Boto Python do AWS z grubsza w następujący sposób (nieprzetestowane, od samego początku):

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

Funkcja ta jest dostępna od wersji 1.24 z AWS SDK dla Ruby i release notes podać przykład także:

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!

Lub:

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

należy użyć nowej odpowiedzi aws clilike @ number5 poniżej docs.aws.amazon.com/cli/latest/reference/s3/rm.html
Don Cheadle

43

Możesz również rozważyć użycie cyklu życia usługi Amazon S3, aby utworzyć datę wygaśnięcia dla plików z prefiksem foo/bar1.

Otwórz konsolę przeglądarki S3 i kliknij zasobnik. Następnie kliknij Właściwości, a następnie Cykl życia.

Utwórz regułę wygasania dla wszystkich plików z prefiksem foo/bar1i ustaw datę na 1 dzień od utworzenia pliku.

Zapisz, a wszystkie pasujące pliki znikną w ciągu 24 godzin.

Po prostu nie zapomnij usunąć reguły po zakończeniu!

Żadnych wywołań API, żadnych bibliotek, aplikacji ani skryptów stron trzecich.

Właśnie usunąłem w ten sposób kilka milionów plików.

Zrzut ekranu przedstawiający okno Reguły cyklu życia (zauważ, że na tym ujęciu prefiks został pozostawiony pusty, wpływając na wszystkie klucze w zasobniku):

wprowadź opis obrazu tutaj


4
Świetny pomysł na użycie cyklu życia zamiast jakiegoś polecenia usuwania.
xis

Dokładnie, niech S3 zrobi to za Ciebie.
Ryan

Możesz również zastosować to do całego zasobnika, umożliwiając usunięcie zasobnika.
Indolering

8

Po s3cmdzainstalowaniu pakietu na komputerze z systemem Linux możesz to zrobić

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


1
Według pomocy jest to usuwanie pojedynczych obiektów s3cmd del s3://BUCKET/OBJECTlub usuwanie całego zasobnika s3cmd rb s3://BUCKET. Nie ma s3cmd rm, przynajmniej według s3cmd --help.
Paul McMurdie,

s3cmd rmjest w pomocy od 2019 r. (jako alias dla del), to doskonała odpowiedź. W awsCLI tylko narzędzia robocze przed /prefiksem kończącej, ale nie folder i częściowe prefiks nazwy pliku, natomiast s3cmd prac w obu przypadkach. Ta odpowiedź wymaga dużo więcej głosów, musiałem przewinąć o wiele za daleko, aby znaleźć właściwe rozwiązanie.
David Parks,

8

W przypadku, gdy chcesz usunąć wszystkie obiekty z prefiksem „foo /” za pomocą 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
Nie mogę znaleźć bardziej wymownej demonstracji tego, czego ludzie nie lubią w Javie, niż ta odpowiedź ...
Jivan

3

W przypadku używania AWS-SKD dla 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

uwaga proszę, wszystkie "foo / *" w zasobniku zostaną usunięte.


2

Właśnie usunąłem wszystkie pliki z mojego zasobnika za pomocą PowerShell:

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

Dziękuję za wysłanie tej odpowiedzi, próbowałem zrobić dokładnie to i wstawiłem -Key "% _. Key", co nie działa.
Scott Gartner


2

W głosowanej odpowiedzi brakuje kroku.

Pomoc dotycząca programu AWS s3:

Obecnie nie ma obsługi używania symboli wieloznacznych w stylu UNIX w argumentach ścieżki polecenia. Jednak większość poleceń ma parametry --exclude "<value>"i --include "<value>"parametry, które mogą osiągnąć pożądany rezultat ......... Gdy istnieje wiele filtrów, regułą jest to, że filtry pojawiające się później w poleceniu mają pierwszeństwo przed filtrami, które pojawiają się wcześniej w poleceniu. Na przykład, jeśli parametry filtru przekazane do polecenia to --exclude "*" --include "*.txt"Wszystkie pliki zostaną wykluczone z polecenia z wyjątkiem plików kończących się na .txt

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

0

Najlepszym sposobem jest użycie reguły cyklu życia w celu usunięcia całej zawartości zasobnika. Programowo możesz użyć następującego kodu (PHP) do PUT reguły cyklu życia.

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

W powyższym przypadku wszystkie obiekty zostaną usunięte. Data rozpoczęcia - „Dzisiaj GMT północ”.

Możesz również określić dni w następujący sposób. Ale w przypadku Dni rozpocznie się usuwanie zawartości zasobnika przez co najmniej 24 godziny (minimum 1 dzień).

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

0

Musiałem wykonać następujące czynności ...

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.