Cách xóa tệp đệ quy khỏi thùng S3


87

Tôi có cấu trúc thư mục sau trong S3. Có cách nào để loại bỏ đệ quy tất cả các tệp trong một thư mục nhất định không (giả sử 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/..

Câu trả lời:


163

Với các công cụ dòng lệnh aws-cli python mới nhất , để xóa một cách đệ quy tất cả các tệp trong một thư mục trong một nhóm chỉ cần:

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

Hoặc xóa mọi thứ trong nhóm:

aws s3 rm --recursive s3://your_bucket_name

Nếu những gì bạn muốn thực sự là xóa nhóm, có một phím tắt gồm một bước:

aws s3 rb --force s3://your_bucket_name

điều này sẽ xóa nội dung trong nhóm đó một cách đệ quy sau đó xóa nhóm.

Lưu ý: s3://tiền tố giao thức là bắt buộc để các lệnh này hoạt động


2
đây sẽ là câu trả lời. Đó là một (mới-ish) tiêu chuẩn, công cụ mạnh mẽ, được thiết kế cho những thứ giống như câu hỏi này
Don Cheadle

Đây là cách xóa các tệp tốt nhưng nó cũng xóa nhóm sau khi xóa các tệp. Tôi có bỏ lỡ điều gì không?
Naveen

1
@Naveen như tôi đã nói ở trên, rmsẽ chỉ xóa tệp nhưng rb --forcesẽ xóa tệp thùng.
số

5
bằng cách sử dụng --recursivexóa cả thư mục.
ryantuck

1
@Moseleyi tôi tin rằng bạn không thể thực sự có một thư mục trống trong một xô s3
ryantuck

58

Điều này từng yêu cầu một lệnh gọi API chuyên dụng cho mỗi khóa (tệp), nhưng đã được đơn giản hóa rất nhiều do sự ra đời của Amazon S3 - Multi-Object Delete vào tháng 12 năm 2011:

Tính năng Xóa nhiều đối tượng mới của Amazon S3 cung cấp cho bạn khả năng xóa tối đa 1000 đối tượng khỏi nhóm S3 chỉ với một yêu cầu.

Xem câu trả lời của tôi cho câu hỏi liên quan xóa khỏi S3 bằng api php sử dụng ký tự đại diện để biết thêm về điều này và các ví dụ tương ứng trong PHP ( AWS SDK cho PHP hỗ trợ điều này kể từ phiên bản 1.4.8 ).

Trong khi đó, hầu hết các thư viện ứng dụng AWS đã giới thiệu hỗ trợ dành riêng cho chức năng này theo cách này hay cách khác, ví dụ:

Python

Bạn có thể đạt được điều này với giao diện Python boto tuyệt vời cho AWS gần như như sau (chưa được kiểm tra, từ đỉnh đầu của tôi):

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

Ruby

Điều này có sẵn kể từ phiên bản 1.24 của AWS SDK cho Ruby và các ghi chú phát hành cũng cung cấp một ví dụ:

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!

Hoặc là:

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

nên sử dụng aws clicâu trả lời mới như @ number5 của bên dưới docs.aws.amazon.com/cli/latest/reference/s3/rm.html
Don Cheadle

43

Bạn cũng có thể cân nhắc sử dụng Amazon S3 Lifecycle để tạo thời hạn cho các tệp có tiền tố foo/bar1.

Mở bảng điều khiển trình duyệt S3 và nhấp vào một nhóm. Sau đó nhấp vào Thuộc tính và sau đó là Vòng đời.

Tạo quy tắc hết hạn cho tất cả các tệp có tiền tố foo/bar1và đặt ngày thành 1 ngày kể từ khi tệp được tạo.

Lưu và tất cả các tệp phù hợp sẽ biến mất trong vòng 24 giờ.

Chỉ cần đừng quên xóa quy tắc sau khi bạn hoàn tất!

Không có lệnh gọi API, không có thư viện, ứng dụng hoặc tập lệnh của bên thứ ba.

Tôi vừa xóa vài triệu tệp theo cách này.

Ảnh chụp màn hình hiển thị cửa sổ Quy tắc Vòng đời (lưu ý trong ảnh này, Tiền tố đã bị bỏ trống, ảnh hưởng đến tất cả các khóa trong nhóm):

nhập mô tả hình ảnh ở đây


4
Ý tưởng tuyệt vời để sử dụng Vòng đời thay vì một số lệnh xóa.
xis

Chính xác, hãy để S3 làm điều đó cho bạn.
Ryan

Bạn cũng có thể áp dụng điều này cho toàn bộ nhóm, cho phép bạn xóa nhóm.
Indolering

8

Trong trường hợp nếu bạn muốn xóa tất cả các đối tượng có tiền tố "foo /" bằng 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
Tôi không thể tìm thấy một minh chứng rõ ràng hơn về những gì mọi người không thích về Java hơn câu trả lời này ...
Jivan

7

Với s3cmdgói được cài đặt trên máy Linux, bạn có thể thực hiện việc này

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


1
Theo sự trợ giúp đó là xóa một đối tượng s3cmd del s3://BUCKET/OBJECThoặc xóa toàn bộ nhóm s3cmd rb s3://BUCKET. Không có s3cmd rm, ít nhất là theo s3cmd --help.
Paul McMurdie

s3cmd rmsẽ được trợ giúp kể từ năm 2019 (như một bí danh cho del), đây là một câu trả lời tuyệt vời. Các awscông cụ cli chỉ hoạt động với /tiền tố kết thúc, nhưng không hoạt động với tiền tố thư mục và một phần tên tệp, trong khi s3cmd hoạt động trong cả hai trường hợp. Câu trả lời này cần nhiều lượt ủng hộ hơn, tôi đã phải cuộn quá xa để tìm ra giải pháp phù hợp.
David Parks

3

Trong trường hợp sử dụng AWS-SKD cho 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

Xin hãy chú ý, tất cả "foo / *" dưới thùng sẽ bị xóa.


2

Tôi vừa xóa tất cả các tệp khỏi nhóm của mình bằng cách sử dụng PowerShell:

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

Cảm ơn bạn đã đăng câu trả lời này, tôi đã cố gắng làm điều này chính xác và đã đặt -Key "% _. Key" mà không hoạt động.
Scott Gartner


1

Câu trả lời được bình chọn còn thiếu một bước.

Per aws s3 giúp đỡ:

Hiện tại, không có hỗ trợ nào cho việc sử dụng ký tự đại diện kiểu UNIX trong đối số đường dẫn của lệnh. Tuy nhiên, hầu hết các lệnh đều có --exclude "<value>"--include "<value>" các tham số có thể đạt được kết quả mong muốn ......... Khi có nhiều bộ lọc, quy tắc là các bộ lọc xuất hiện sau trong lệnh được ưu tiên hơn các bộ lọc xuất hiện trước đó trong lệnh. Ví dụ: nếu các tham số bộ lọc được truyền cho lệnh là --exclude "*" --include "*.txt"Tất cả các tệp sẽ bị loại trừ khỏi lệnh ngoại trừ các tệp kết thúc bằng .txt

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

0

Cách tốt nhất là sử dụng quy tắc vòng đời để xóa toàn bộ nội dung nhóm. Theo chương trình, bạn có thể sử dụng mã sau (PHP) để quy tắc vòng đời 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',
                ),
            ),
        ));

Trong trường hợp trên, tất cả các đối tượng sẽ bị xóa bắt đầu từ Ngày - "Nửa đêm GMT hôm nay".

Bạn cũng có thể chỉ định Ngày như sau. Nhưng với Days, nó sẽ đợi ít nhất 24 giờ (tối thiểu là 1 ngày) để bắt đầu xóa nội dung nhóm.

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

0

Tôi cần làm những việc sau ...

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.