Як рекурсивно видаляти файли з сегмента S3


87

У мене така структура папок у 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/..

Відповіді:


163

За допомогою найновіших інструментів командного рядка aws-cli python рекурсивно видалити всі файли в папці у відрі просто:

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://для роботи цих команд потрібен префікс протоколу


2
це має бути відповіддю. Це (новий іш) стандартний потужний інструмент, розроблений для речей, подібних до цього питання
Дон Чідл,

Це видаляє файли дуже добре, але також видаляє сегмент після видалення файлів. Я щось пропустив?
Naveen

1
Як я вже говорив вище, @Naveen rmбуде видаляти лише файли, але rb --forceвидалятиме файли та сегмент.
номер 5

5
використання також --recursiveвидаляє папку.
ryantuck

1
@Moseleyi я вважаю, що насправді не можна мати порожню папку у відрі s3
ryantuck,

58

Раніше це вимагало спеціального виклику API для кожного ключа (файлу), але було значно спрощене завдяки введенню Amazon S3 - Multi-Object Delete у грудні 2011 року:

Нове багатооб'єктне видалення Amazon S3 дає можливість видалити до 1000 об'єктів із сегмента S3 за один запит.

Дивіться мою відповідь на відповідне запитання щодо видалення з S3 за допомогою api php із використанням підстановочного символу, щоб дізнатись більше про це та відповідні приклади в PHP ( AWS SDK для PHP підтримує це з версії 1.4.8 ).

Більшість клієнтських бібліотек AWS тим часом впровадили спеціальну підтримку цієї функції так чи інакше, наприклад:

Python

Ви можете досягти цього за допомогою чудового інтерфейсу boto Python для AWS, приблизно таким чином (неперевірений, з верхньої частини моєї голови):

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

Рубін

Ця функція доступна починаючи з версії 1,24 з AWS SDK для 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)

слід використати нову відповідь aws cliтипу @ number5 нижче docs.aws.amazon.com/cli/latest/reference/s3/rm.html
Дон Чідл

43

Ви також можете розглянути можливість використання Amazon S3 Lifecycle для створення терміну дії файлів із префіксом foo/bar1.

Відкрийте консоль браузера S3 і натисніть сегмент. Потім натисніть Властивості, а потім LifeCycle.

Створіть правило закінчення терміну дії для всіх файлів із префіксом foo/bar1і встановіть дату 1 день з моменту створення файлу.

Збережіть, і всі відповідні файли зникнуть протягом 24 годин.

Тільки не забудьте видалити правило після закінчення!

Ніяких викликів API, жодних сторонніх бібліотек, програм чи сценаріїв.

Я щойно видалив кілька мільйонів файлів таким чином.

Знімок екрана, що відображає вікно Правила життєвого циклу (зауважте, на цьому знімку префікс залишився порожнім, що впливає на всі клавіші у відрі):

введіть тут опис зображення


4
Чудова ідея використовувати життєвий цикл замість якоїсь команди видалення.
xis

Точно, нехай S3 зробить це за вас.
Райан

Ви також можете застосувати це до всього сегмента, що дозволяє видалити сегмент.
Іноділінг

8

Якщо ви хочете видалити всі об'єкти з префіксом "foo /", використовуючи 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
Я не можу знайти більш показової демонстрації того, що людям не подобається в Java, ніж ця відповідь ...
Джіван,

7

З s3cmdпакетом, встановленим на машині Linux, ви можете це зробити

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


1
Згідно з довідкою, це або видалення одного об’єкта, s3cmd del s3://BUCKET/OBJECTабо видалення цілого сегмента s3cmd rb s3://BUCKET. Немає s3cmd rm, принаймні згідно з s3cmd --help.
Paul McMurdie

s3cmd rmє в довідці станом на 2019 рік (як псевдонім для del), це відмінна відповідь. Інструменти awscli працюють лише з /префіксом, що закінчується, але не з префіксом папки та часткового імені файлу, тоді як s3cmd працює в обох випадках. Ця відповідь потребує набагато більше голосів, мені довелося прокрутити занадто далеко, щоб знайти правильне рішення.
Девід Паркс,

3

У разі використання 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

будь ласка, будь ласка, всі "foo / *" під сегментом буде видалено.


2

Я щойно видалив усі файли зі свого сегмента за допомогою PowerShell:

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

Дякую за розміщення цієї відповіді, я намагався зробити саме цю річ і поставив -Key "% _. Ключ", який не працює.
Скотт Гартнер


1

Відповідь, за яку проголосували, відсутній крок.

За допомогою aws s3:

Наразі немає підтримки використання символів узагальнення UNIX у аргументах шляху команди. Однак більшість команд мають --exclude "<value>"і --include "<value>" параметри, за допомогою яких можна досягти бажаного результату ......... Коли є кілька фільтрів, правило полягає в тому, що фільтри, які з'являються пізніше в команді, мають перевагу над фільтрами, які з'являються раніше в команді. Наприклад, якщо параметри фільтра, передані команді, --exclude "*" --include "*.txt"усі команди будуть виключені з команди, за винятком файлів, що закінчуються на .txt

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

0

Найкращий спосіб - використовувати правило життєвого циклу, щоб видалити весь вміст сегмента. Програмно ви можете використовувати наступний код (PHP) для ВСТАНОВЛЕННЯ правила життєвого циклу.

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

0

Мені потрібно було зробити наступне ...

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.