LoginSignup
1
0

aws cliでS3バケット内の全オブジェクトの情報を取得する

Posted at

はじめに

S3バッチオペレーションを試したいなーと思ったのですが、インプットに以下の形式のcsvが必要なようでした。

CSV 形式のマニフェスト(バージョン ID なし)の例を以下に示します。
Examplebucket,objectkey1
Examplebucket,objectkey2
Examplebucket,objectkey3
Examplebucket,photos/jpgs/objectkey4
Examplebucket,photos/jpgs/newjersey/objectkey5
Examplebucket,object%20key%20with%20spaces

バージョン ID を含む CSV 形式のマニフェストの例は次のとおりです。
Examplebucket,objectkey1,PZ9ibn9D5lP6p298B7S9_ceqx1n5EJ0p
Examplebucket,objectkey2,YY_ouuAJByNW1LRBfFMfxMge7XQWxMBF
Examplebucket,objectkey3,jbo9_jhdPEyB4RrmOxWS0kU0EoNrU_oI
Examplebucket,photos/jpgs/objectkey4,6EqlikJJxLTsHsnbZbSRffn24_eh5Ny4
Examplebucket,photos/jpgs/newjersey/objectkey5,imHf3FAiRsvBW_EHB8GOu.NHunHO1gVs
Examplebucket,object%20key%20with%20spaces,9HkPvDaZY5MVbMhn6TMn1YTb5ArQAo3w

jqや --query オプションに苦手意識があったので、克服も兼ねて色々やってみました!

リファレンス

aws cliのバージョンは2.5.2です(アプデしないと・・・)

$ aws --version
aws-cli/2.5.2 Python/3.9.11 

参考にしたドキュメントです

やってみた

準備

4つのオブジェクトが保存されているバケットを用意しました。

cap1.PNG

特定のバケットのオブジェクトを全量取得する

コマンド

aws s3api list-objects-v2 \
--bucket test-batch-ope-ito-log-a8f2ms

--bucket
 対象バケット名を指定します

実行結果

$ aws s3api list-objects-v2 --bucket test-batch-ope-ito-log-a8f2ms
{
    "Contents": [
        {
            "Key": "cap.jpg",
            "LastModified": "2024-05-11T03:13:47+00:00",
            "ETag": "\"5ee32753dd30e0580d8075ff5a228921\"",
            "Size": 44575,
            "StorageClass": "STANDARD"
        },
        {
            "Key": "memo.txt",
            "LastModified": "2024-05-11T03:13:14+00:00",
            "ETag": "\"6436a6c961b90c90682e8fa52e03a6f2\"",
            "Size": 1161,
            "StorageClass": "STANDARD"
        },
        {
            "Key": "shot.jpg",
            "LastModified": "2024-05-11T03:32:50+00:00",
            "ETag": "\"cd4854823f017f45f391161fb53e6c28\"",
            "Size": 209678,
            "StorageClass": "STANDARD"
        },
        {
            "Key": "test.csv",
            "LastModified": "2024-05-11T03:14:28+00:00",
            "ETag": "\"d41d8cd98f00b204e9800998ecf8427e\"",
            "Size": 0,
            "StorageClass": "STANDARD"
        }
    ]
}

4要素ある配列が帰ってきました!
バージョン情報は保持していないようです

特定のサイズのファイルだけを取得する

0kbのファイルを除外するケースを考えてみます。

コマンド

aws s3api list-objects-v2 --bucket test-batch-ope-ito-log-a8f2ms \
--query 'Contents[?Size > `0`]'

--query 'Contents[?Size > `0`]'
 オブジェクト配列の各要素のSizeの値でfilterします

実行結果

$ aws s3api list-objects-v2 --bucket test-batch-ope-ito-log-a8f2ms --query 'Contents[?Size > `0`]'
[
    {
        "Key": "cap.jpg",
        "LastModified": "2024-05-11T03:13:47+00:00",
        "ETag": "\"5ee32753dd30e0580d8075ff5a228921\"",
        "Size": 44575,
        "StorageClass": "STANDARD"
    },
    {
        "Key": "memo.txt",
        "LastModified": "2024-05-11T03:13:14+00:00",
        "ETag": "\"6436a6c961b90c90682e8fa52e03a6f2\"",
        "Size": 1161,
        "StorageClass": "STANDARD"
    },
    {
        "Key": "shot.jpg",
        "LastModified": "2024-05-11T03:32:50+00:00",
        "ETag": "\"cd4854823f017f45f391161fb53e6c28\"",
        "Size": 209678,
        "StorageClass": "STANDARD"
    }
]

配列の要素数が3つになって帰ってきました!
0byteのtest.csvをfilterの結果はじけてますね

特定の拡張子のファイルだけを取得する

aws cliのqueryでは正規表現は使えなさそうでした
jqでfilterします

コマンド

aws s3api list-objects-v2 \
--bucket test-batch-ope-ito-log-a8f2ms | \
jq -r '.Contents[] | select(.Key | endswith(".jpg"))'

jq -r '.Contents[] | select(.Key | endswith(".jpg"))'
 Contents[]内の各要素に対し、Keyが".jpg"で終わるものをfilterします

実行結果

$ aws s3api list-objects-v2 --bucket test-batch-ope-ito-log-a8f2ms | jq -r '.Contents[] | select(.Key | endswith(".jpg"))'
{
  "Key": "cap.jpg",
  "LastModified": "2024-05-11T03:13:47+00:00",
  "ETag": "\"5ee32753dd30e0580d8075ff5a228921\"",
  "Size": 44575,
  "StorageClass": "STANDARD"
}
{
  "Key": "shot.jpg",
  "LastModified": "2024-05-11T03:32:50+00:00",
  "ETag": "\"cd4854823f017f45f391161fb53e6c28\"",
  "Size": 209678,
  "StorageClass": "STANDARD"
}

jpgである2ファイルのみ取得できました!

取得期間を指定する

特定の期間内にputされたオブジェクトのみを取得するケースを考えます

コマンド

aws s3api list-objects-v2 --bucket test-batch-ope-ito-log-a8f2ms \
--query 'Contents[?LastModified >=`2024-05-11T03:14`] | [?LastModified <= `2024-05-11T03:15`]'

--query 'Contents[?LastModified >=`2024-05-11T03:14`]
LastModifiedが特定の時間以降のオブジェクトをfilterしています

| [?LastModified <= `2024-05-11T03:15`]'
上記filter結果を、パイプ処理で再度filterしています

実行結果

$ aws s3api list-objects-v2 --bucket test-batch-ope-ito-log-a8f2ms --query 'Contents[?LastModified >=`2024-05-11T03:14`] | [?LastModified <= `2024-05-11T03:15`]'
[
    {
        "Key": "test.csv",
        "LastModified": "2024-05-11T03:14:28+00:00",
        "ETag": "\"d41d8cd98f00b204e9800998ecf8427e\"",
        "Size": 0,
        "StorageClass": "STANDARD"
    }
]

特定の期間にPUTされたオブジェクトのみ取得できました!

ページネーションを行う

オブジェクトの量が多い場合、ページネーション処理が必要になります

コマンド

aws s3api list-objects-v2 --bucket test-batch-ope-ito-log-a8f2ms \
--max-items 2

--max-items 2
 一度に取得するオブジェクト数の上限を意図的に下げ、ページネーションを確認します

実行結果

$ aws s3api list-objects-v2 --bucket test-batch-ope-ito-log-a8f2ms --max-items 2
{
    "Contents": [
        {
            "Key": "cap.jpg",
            "LastModified": "2024-05-11T03:13:47+00:00",
            "ETag": "\"5ee32753dd30e0580d8075ff5a228921\"",
            "Size": 44575,
            "StorageClass": "STANDARD"
        },
        {
            "Key": "memo.txt",
            "LastModified": "2024-05-11T03:13:14+00:00",
            "ETag": "\"6436a6c961b90c90682e8fa52e03a6f2\"",
            "Size": 1161,
            "StorageClass": "STANDARD"
        }
    ],
    "NextToken": "eyJDb250aW51YXRpb25Ub2tlbiI6IG51bGwsICJib3RvX3RydW5jYXRlX2Ftb3VudCI6IDJ9"
}

2つのオブジェクトのみが返却されました。
また、ページネーション用のNextTokenが合わせて返却されています

コマンド

aws s3api list-objects-v2 --bucket test-batch-ope-ito-log-a8f2ms \
--max-items 2 \
--starting-token eyJDb250aW51YXRpb25Ub2tlbiI6IG51bGwsICJib3RvX3RydW5jYXRlX2Ftb3VudCI6IDJ9

--starting-token eyJDb250aW51YXRpb25Ub2tlbiI6IG51bGwsICJib3RvX3RydW5jYXRlX2Ftb3VudCI6IDJ9
 先ほど取得したTokenをリクエストに付与し、ページ処理を行います

$ aws s3api list-objects-v2 --bucket test-batch-ope-ito-log-a8f2ms --max-items 2 --starting-token eyJDb250aW51YXRpb25Ub2tlbiI6IG51bGwsICJib3RvX3RydW5jYXRlX2Ftb3VudCI6IDJ9
{
    "Contents": [
        {
            "Key": "shot.jpg",
            "LastModified": "2024-05-11T03:32:50+00:00",
            "ETag": "\"cd4854823f017f45f391161fb53e6c28\"",
            "Size": 209678,
            "StorageClass": "STANDARD"
        },
        {
            "Key": "test.csv",
            "LastModified": "2024-05-11T03:14:28+00:00",
            "ETag": "\"d41d8cd98f00b204e9800998ecf8427e\"",
            "Size": 0,
            "StorageClass": "STANDARD"
        }
    ]
}

無事次の2オブジェクトが取得できました!

csv形式でoutputする

S3バッチオペレーションをしたかったことを思い出しました
S3バッチオペレーションのinputとなるcsvは以下の通りです

Examplebucket,objectkey1
Examplebucket,objectkey2
Examplebucket,objectkey3
Examplebucket,photos/jpgs/objectkey4
Examplebucket,photos/jpgs/newjersey/objectkey5
Examplebucket,object%20key%20with%20spaces

コマンド

aws s3api list-objects-v2 --bucket test-batch-ope-ito-log-a8f2ms \
--query 'Contents[?Size > `0`].[`replace_target`,Key]' \
--output text | sed 's/\t/,/g'

--query 'Contents[?Size > `0`].[`replace_target`,Key]'
 Sizeが0以上のオブジェクトに対し、"replace_target"という固定文字列と、Keyを取得しています
 ドキュメントにあるように、CSVの1カラム目はバケット名になるようなので、ファイル出力後にまとめて置換するために適当な文字列を1列目に指定しています

--output text | sed 's/\t/,/g'
 平文形式で出力します。TSV形式で出力されるので、sedでCSVに変換します

実行結果

$ aws s3api list-objects-v2 --bucket test-batch-ope-ito-log-a8f2ms --query 'Contents[?Size > `0`].[`replace_target`,Key]' --output text | sed 's/\t/,/g'
replace_target,cap.jpg
replace_target,memo.txt
replace_target,shot.jpg

いいかんじ!

バージョンもあわせて出力する

バージョニングを有効化していたのですが、list-objects-v2 コマンドではバージョンが確認できませんでした
調べたところ、list-object-versions というコマンドがあったので、そちらを使用してみました

コマンド

aws s3api list-object-versions \
--bucket test-batch-ope-ito-log-a8f2ms 

実行結果

$ aws s3api list-object-versions --bucket test-batch-ope-ito-log-a8f2ms 
{
    "Versions": [
        {
            "ETag": "\"5ee32753dd30e0580d8075ff5a228921\"",
            "Size": 44575,
            "StorageClass": "STANDARD",
            "Key": "cap.jpg",
            "VersionId": "M0.fTixy2AUAXCD.idyCo_pdzlhiEwkC",
            "IsLatest": true,
            "LastModified": "2024-05-11T03:49:27+00:00",
            "Owner": {
                "DisplayName": "aaaaaaaaaaaaaaaaaaaa",
                "ID": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
            }
        },
        {
            "ETag": "\"6436a6c961b90c90682e8fa52e03a6f2\"",
            "Size": 1161,
            "StorageClass": "STANDARD",
            "Key": "memo.txt",
            "VersionId": "h5Mbjk9gs81zvkO2rXfe24MLctULprNp",
            "IsLatest": true,
            "LastModified": "2024-05-11T03:52:08+00:00",
            "Owner": {
                "DisplayName": "aaaaaaaaaaaaaaaaaaaa",
                "ID": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
            }
        },
        {
            "ETag": "\"cd4854823f017f45f391161fb53e6c28\"",
            "Size": 209678,
            "StorageClass": "STANDARD",
            "Key": "shot.jpg",
            "VersionId": "EQWuUogRNFOPt_npUfdTv9xFE1I2B146",
            "IsLatest": true,
            "LastModified": "2024-05-11T03:56:42+00:00",
            "Owner": {
                "DisplayName": "aaaaaaaaaaaaaaaaaaaa",
                "ID": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
            }
        },
        {
            "ETag": "\"cd4854823f017f45f391161fb53e6c28\"",
            "Size": 209678,
            "StorageClass": "STANDARD",
            "Key": "shot.jpg",
            "VersionId": "wzLukGRVNHbR4Bgh.wRoIYwEZ58big99",
            "IsLatest": false,
            "LastModified": "2024-05-11T03:50:27+00:00",
            "Owner": {
                "DisplayName": "aaaaaaaaaaaaaaaaaaaa",
                "ID": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
            }
        },
        {
            "ETag": "\"d41d8cd98f00b204e9800998ecf8427e\"",
            "Size": 0,
            "StorageClass": "STANDARD",
            "Key": "test.csv",
            "VersionId": "XbA2AR542oaNIZRxkW6LADyBZMm34r53",
            "IsLatest": true,
            "LastModified": "2024-05-11T03:49:27+00:00",
            "Owner": {
                "DisplayName": "aaaaaaaaaaaaaaaaaaaa",
                "ID": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
            }
        }
    ]
}

2世代あるshot.jpgがどちらのバージョンも表示されています、良いですね!

おわりに

jqや --query コマンドのいい練習になりました!
他のAWS CLIコマンドでもガンガン使っていきたいです

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0