lấy đối tượng sửa đổi cuối cùng từ S3 CLI


80

Tôi có một trường hợp sử dụng trong đó tôi lập trình đưa ra một phiên bản EC2, sao chép và tệp thực thi từ S3, chạy nó và tắt phiên bản đó (được thực hiện trong dữ liệu người dùng). Tôi chỉ cần lấy tệp được thêm cuối cùng từ S3. Có cách nào để lấy tệp / đối tượng được sửa đổi cuối cùng từ thùng S3 bằng CLI không?


bạn có thể liên quan đến một ngôn ngữ lập trình nào cả
Drew

CLI sẽ là lựa chọn tốt nhất vì tôi dự định có nó trong dữ liệu người dùng khi khởi chạy phiên bản.
khôn ngoan,

Bạn có lập trình bằng bất kỳ ngôn ngữ nào với s3 không?
Drew

1
Có giải pháp nào tốt hơn cho nhóm có 2M + đối tượng không?
alonewarrior556

1
Đối với rất nhiều đối tượng, tôi nghĩ giải pháp tốt hơn sẽ là tạo một Event/Lambdađối tượng trên đối tượng được kích hoạt ObjectCreation. tìm nạp đối tượng cuối cùng trong số hơn 2 triệu đối tượng bằng s3 cli hoặc api là cách để làm chậm hơn.
Vaulstein

Câu trả lời:


174

Bạn có thể liệt kê tất cả các đối tượng trong thùng với aws s3 ls $BUCKET --recursive:

$ aws s3 ls $BUCKET --recursive
2015-05-05 15:36:17          4 an_object.txt
2015-06-08 14:14:44   16322599 some/other/object
2015-04-29 12:09:29      32768 yet-another-object.sh

Chúng được sắp xếp theo thứ tự bảng chữ cái theo khóa, nhưng cột đầu tiên đó là lần sửa đổi cuối cùng. Nhanh chóng sortsẽ sắp xếp lại chúng theo ngày:

$ aws s3 ls $BUCKET --recursive | sort
2015-04-29 12:09:29      32768 yet-another-object.sh
2015-05-05 15:36:17          4 an_object.txt
2015-06-08 14:14:44   16322599 some/other/object

tail -n 1chọn hàng cuối cùng và awk '{print $4}'trích xuất cột thứ tư (tên của đối tượng).

$ aws s3 ls $BUCKET --recursive | sort | tail -n 1 | awk '{print $4}'
some/other/object

Cuối cùng nhưng không kém phần quan trọng, hãy thả nó vào aws s3 cpđể tải xuống đối tượng:

$ KEY=`aws s3 ls $BUCKET --recursive | sort | tail -n 1 | awk '{print $4}'`
$ aws s3 cp s3://$BUCKET/$KEY ./latest-object

2
Bài viết rực rỡ. Đặc biệt hữu ích do các giải thích của mỗi lệnh. Cảm ơn.
Christian

4
S3 chỉ lập chỉ mục các đối tượng theo khóa. Nếu nhóm có đủ đối tượng mà việc "quét toàn bộ bảng" để tìm đối tượng bạn đang tìm là không thực tế, bạn sẽ cần phải xây dựng một chỉ mục riêng của mình. Lựa chọn lười nhất mà tôi có thể nghĩ đến là đặt khóa của đối tượng được viết gần đây nhất vào s3: // $ BUCKET / current sau khi bạn viết xong, và yêu cầu người đọc nhìn vào đó để tìm đối tượng mà họ nên lấy.
David Murray

Chỉ cần một mặt lưu ý, nếu bạn muốn điều tương tự cho một "thư mục" toàn bộ, awksẽ cần phải chọn phần tử thứ hai (thay vì thứ 4) và --recursivesẽ là cần thiết, ví dụ như,KEY=`aws s3 ls $BUCKET --recursive | sort | tail -n 1 | awk '{print $2}'` ; aws s3 cp s3://$BUCKET/$KEY ./latest-object --recursive
David Arenburg

3
Điều này sẽ không hoạt động trên các nhóm có hơn 1000 mặt hàng, vì đó là số lượng nhiều nhất có thể được trả lại docs.aws.amazon.com/cli/latest/reference/s3/ls.html
nico

dòng này sẽ không hoạt động aws s3 cp s3://$BUCKET/$KEY ./latest-object, tập lệnh trước đó sẽ trở lại"object"
Madeo

23

Sau một thời gian, có một bản cập nhật nhỏ cách thực hiện điều đó một chút:

aws s3api list-objects-v2 --bucket "my-awesome-bucket" --query 'sort_by(Contents, &LastModified)[-1].Key' --output=text

Thay vì reversechức năng bổ sung, chúng ta có thể lấy mục cuối cùng từ danh sách qua[-1]

Câu trả lời cũ:

Lệnh này chỉ thực hiện công việc mà không có bất kỳ phụ thuộc bên ngoài nào:

aws s3api list-objects-v2 --bucket "my-awesome-bucket" --query 'reverse(sort_by(Contents, &LastModified))[:1].Key' --output=text

3
Thông minh. Nếu bạn cũng cần tên đối tượng để phù hợp với một chuỗi nhất định:--query 'reverse(sort_by(Contents[?contains(Key, `myKey`)], &LastModified))[:1].Key'
bfcapell

5
--query được thực thi cục bộ, vì vậy nếu bạn có hơn 1000 tệp trong nhóm, bạn không được đảm bảo nhận được những tệp được sửa đổi cuối cùng trước.
Gismo Ranas

@GismoRanas Điểm tốt. Các thường xuyên --filterlựa chọn có thể được áp dụng để giảm một danh sách
Roman Shishkin

11
aws s3api list-objects-v2 --bucket "bucket-name" |jq  -c ".[] | max_by(.LastModified)|.Key"

Nếu bạn chưa bao giờ gặp JQ trước đây, đó là một bộ xử lý json stedolan.github.io/jq
andrew Lorien

3
Tôi nghĩ rằng list-objects-v2có giới hạn đối với các mục tối đa, vì vậy nếu nhóm của bạn có nhiều đối tượng hơn thế - điều này có thể không nhận được câu trả lời chính xác
Gilad Peleg

docs.aws.amazon.com/cli/latest/reference/s3api/… tuyên bố (tính đến thời điểm viết bài này) rằng giới hạn tối đa trên mỗi trang là 1000. Cũng lưu ý rằng đầu ra đã IsTruncatedđược đặt thành true nếu có nhiều phím hơn để trả về.
Ashutosh Jindal

2

Sau đây là tập lệnh bash, tải xuống tệp mới nhất từ ​​Nhóm S3. Thay vào đó, tôi đã sử dụng lệnh AWS S3 Synch để nó không tải xuống tệp từ S3 nếu đã tồn tại.

--exclude, loại trừ tất cả các tệp

- bao gồm, bao gồm tất cả các tệp phù hợp với mẫu

#!/usr/bin/env bash

    BUCKET="s3://my-s3-bucket-eu-west-1/list/"
    FILE_NAME=`aws s3 ls $BUCKET  | sort | tail -n 1 | awk '{print $4}'`
    TARGET_FILE_PATH=target/datdump/
    TARGET_FILE=${TARGET_FILE_PATH}localData.json.gz

    echo $FILE_NAME
    echo $TARGET_FILE

    aws s3 sync $BUCKET $TARGET_FILE_PATH --exclude "*" --include "*$FILE_NAME*"

    cp target/datdump/$FILE_NAME $TARGET_FILE

ps Cảm ơn @David Murray


1

Nếu đây là tệp mới được tải lên, bạn có thể sử dụng Lambda để thực thi một đoạn mã trên đối tượng S3 mới.

Nếu bạn thực sự cần lấy tệp mới nhất, bạn có thể đặt tên tệp với ngày trước, sắp xếp theo tên và lấy đối tượng đầu tiên.


2
Rất tiếc, đây không phải là một tệp mới được tải lên. Tôi sẽ cần tệp tải lên cuối cùng có thể được tải lên bất cứ lúc nào.
khôn ngoan
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.