Подтвердить что ты не робот

Как рекурсивно удалять файлы из ведра S3

У меня есть следующая структура папок в 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/..
4b9b3361

Ответ 1

С помощью последних инструментов командной строки python aws-cli, чтобы рекурсивно удалить все файлы под папкой в ​​ведро:

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

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

Новая функция Multi-Object Delete от Amazon S3 позволяет вам удалять до 1000 объектов из корзины S3 за один запрос.

См. Мой ответ на соответствующий вопрос об удалении из S3 с использованием api php с использованием подстановочного знака для получения дополнительной информации об этом и соответствующих примерах в PHP (AWS SDK для PHP поддерживает это начиная с версии 1.4.8).

В то же время большинство клиентских библиотек AWS так или иначе ввели специальную поддержку для этих функций, например:

питон

Вы можете добиться этого с помощью превосходного интерфейса Python boto к 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)

Ответ 3

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

Откройте консоль браузера S3 и выберите ковш. Затем нажмите "Свойства", а затем "Жизненный цикл".

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

Сохранить, и все соответствующие файлы исчезнут в течение 24 часов.

Просто не забудьте удалить правило после того, как все будет готово!

Нет вызовов API, нет сторонних библиотек, приложений или скриптов.

Я просто удалил несколько миллионов файлов таким образом.

Снимок экрана с окном Lifecycle Rule (обратите внимание, что в этом снимке префикс оставлен пустым, что влияет на все клавиши в ковше):

enter image description here

Ответ 4

Если вы хотите удалить все объекты с помощью префикса "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;
};

Ответ 5

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

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

Ответ 6

С пакетом s3cmd, установленным на машине Linux, вы можете сделать это

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

Ответ 7

В случае использования 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/*" под ведром удалит.

Ответ 9

Лучший способ - использовать правило жизненного цикла для удаления всего содержимого ведра. Программно вы можете использовать следующий код (PHP) для правила жизненного цикла PUT.

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

Ответ 10

Мне нужно было сделать следующее...

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

Ответ 11

В проголосовавшем ответе не хватает шага.

Per aws s3 help:

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

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