S3 オブジェクトの一覧をあまり手間をかけずに AWS CLI で取得する
S3 オブジェクトの一覧を取得したい
コンバンハ、千葉(幸)です。
S3 バケットに格納されているオブジェクトの一覧を取得したい、という時がありました。
単発の棚卸し的な用途であったため、そのために作り込みをしたり何かの機能を有効化したりしたくありません。AWS CLI が使えれば要件を満たせるかもと思って調べたところ、ひと工夫だけ必要であったためその足跡を残しておきます。
まとめ
以下コマンドを実行すれば比較的お手軽にオブジェクト一覧が取得できる。
aws s3 ls バケット名 --recursive | grep -v '/$' | awk '{print $4}' > result.txt
--recursive
オプションによって再帰的に一覧を取得しているgrep -v '/$'
によって「末尾が/
」であるプレフィックスを結果から除外しているawk '{print $4}'
によってオブジェクト名のみを出力している
アクセスキーの払い出しといった事前準備が不要なため、AWS CloudShell での実行がオススメです。わたしの環境では、約110万オブジェクトを対象にして実行したところおよそ 20 分で出力が完了しました。
aws s3 ls によるバケット内のオブジェクト一覧の出力
今回使用する aws s3 ls は、バケットの一覧もしくはオブジェクトの一覧を出力できるコマンドです。
バケットを引数に指定して実行すると、バケットのルート直下のオブジェクトを出力してくれます。「PRE」と表示されているのはプレフィックス(コンソールでは「フォルダ」と表現される)を表します。
$ aws s3 ls chibayuki-test-test PRE folderA/ PRE folderB/ 2023-02-27 12:48:13 750 test.json 2023-02-27 12:47:39 5 test.txt
↑プレフィックスは末尾が「/
で表されます。
--recursive
オプションを付与することでプレフィックス配下のオブジェクトも再帰的に出力されます。
$ aws s3 ls chibayuki-test-test --recursive 2023-02-27 12:48:30 0 folderA/ 2023-02-27 12:51:16 5 folderA/test_a.txt 2023-02-27 12:48:52 0 folderB/ 2023-02-27 12:51:33 5 folderB/test_b.txt 2023-02-27 12:48:13 750 test.json 2023-02-27 12:47:39 5 test.txt
今回はあまり関係ありませんが、以下オプションを付与することで少し嬉しい場合があります。
--summarize
オプション:オブジェクト数とトータルサイズのサマリを追加--human-readable
オプション:サイズを人間が読みやすい単位で表示
$ aws s3 ls chibayuki-test-test --recursive --summarize --human-readable 2023-02-27 12:48:30 0 Bytes folderA/ 2023-02-27 12:51:16 5 Bytes folderA/test_a.txt 2023-02-27 12:48:52 0 Bytes folderB/ 2023-02-27 12:51:33 5 Bytes folderB/test_b.txt 2023-02-27 12:48:13 750 Bytes test.json 2023-02-27 12:47:39 5 Bytes test.txt Total Objects: 6 Total Size: 765 Bytes
特定のプレフィックス配下のオブジェクトのみを表示したいときは、引数にプレフィックスを追加します。
$ aws s3 ls chibayuki-test-test/folderA --recursive --summarize --human-readable 2023-02-27 12:48:30 0 Bytes folderA/ 2023-02-27 12:51:16 5 Bytes folderA/test_a.txt Total Objects: 2 Total Size: 5 Bytes
↑ここではchibayuki-test-test/folderA
配下のみを表示しています。
aws s3 ls コマンドの出力結果を加工する
ここまで見てきた内容にひと工夫を加えれば、「オブジェクト一覧のみの出力」が実現できます。
grep -v '/$'
で末尾が/
であるプレフィックスを除外。
$ aws s3 ls chibayuki-test-test --recursive | grep -v '/$' 2023-02-27 12:51:16 5 folderA/test_a.txt 2023-02-27 12:51:33 5 folderB/test_b.txt 2023-02-27 12:48:13 750 test.json 2023-02-27 12:47:39 5 test.txt
awk '{print $4}'
で 4 番目のカラムのみを出力。
$ aws s3 ls chibayuki-test-test --recursive | awk '{print $4}' folderA/ folderA/test_a.txt folderB/ folderB/test_b.txt test.json test.txt
組み合わせた結果を特定のファイル(ここではresult.txt
)に出力。
$ aws s3 ls chibayuki-test-test --recursive | grep -v '/$' | awk '{print $4}' > result.txt $ cat result.txt folderA/test_a.txt folderB/test_b.txt test.json test.txt
もちろん作成日時やオブジェクトサイズを削らずに出力することも可能です。要件に応じてカスタマイズしてみてください。
110 万件の S3 オブジェクト一覧を出力してみた
オブジェクト数が大量であるときにも耐えうる手法なのかが気になったため、100万超のオブジェクトが格納された S3 バケットを対象に実行してみます。実行環境には AWS CloudShell を選択します。
オブジェクト数は S3 コンソールの「メトリクス→オブジェクトの合計数」や、Storage Lens のデフォルトダッシュボードから確認できます。
今回は Storage Lens の方から確認しました。1.1 M 、およそ 110 万個のオブジェクト数であることが分かります。
以下の 3 つの観点を気にしてみます。
- リクエストにかかる料金
- 所要時間
- 出力結果のファイルサイズ
リクエストにかかる料金
2023年2月時点の東京リージョンのスタンダードクラスの S3 バケットでは、1,000 LIST リクエストあたり 0.0047 USD の料金がかかります。
ひとつの LIST リクエストごとに 1,000 件のオブジェクトを取得できるため、110 万件のオブジェクトを対象にした場合の料金を考えると以下になります。
- リクエストの回数:
- 1,100,000(オブジェクト数) / 1,000(1リクエストあたりの取得数) = 1,100 リクエスト
- リクエストの料金:
- 0.0047(1,000 リクエストあたりの料金)* 1.1 = 0.00517 USD
ほぼ無視できる範囲の料金であることが分かりました。
所要時間
前後に date コマンドを挟んで実際に計測してみました。
$ date; aws s3 ls cm-chiba-vpc-flowlog --recursive | grep -v '/$' | awk '{print $4}' > result.txt; date Mon Feb 27 14:08:41 UTC 2023 Mon Feb 27 14:29:05 UTC 2023
わたしの環境ではおよそ 20 分で実行が完了しました。
AWS CloudShell で実行する場合、20~30分間操作がないとシェルセッションが終了すると仕様があるため注意しましょう。(わたしはコマンドの待機中に適当なキーを打ったりして終了を回避しました。)
出力結果のファイルサイズ
先ほどの出力結果を確認すると 165 MB でした。
$ ls -goh | grep result -rw-rw-r-- 1 165M Feb 27 14:03 result.txt
AWS CloudShell のストレージは 1GB となっているため、オブジェクト数やオブジェクト名が長い場合には注意が必要そうです。
実行前に大まかなサイズ感を計るには、S3 URI を用いるとよいでしょう。今回対象にしたバケットに格納されていたオブジェクトをひとつピックアップして S3 URI を確認すると、以下の通りです。
s3://cm-chiba-vpc-flowlog/AWSLogs/000000000000/vpcflowlogs/ap-northeast-1/2023/02/27/000000000000_vpcflowlogs_ap-northeast-1_fl-010f7d1bef7c0e169_20230227T0000Z_92fb2273.log.gz
S3://バケット名/
を除いたオブジェクト名をカウントすると 150 バイトです。これと同程度のオブジェクト名が 110 万件あるとすると、およそ 165 MB であると試算できます。
出力結果を AWS CloudShell からダウンロードする
AWS CloudShell 上で出力したファイルをローカルの端末にダウンロードできます。(事前にダウンロードしたいファイルのパスを確認しておきましょう。)
「Actions」→「Download file」を押下します。
ファイルのパスを入力し「Download」を押下します。ホームディレクトリ/home/cloudshell-user
は省略できます。
↑今回はホームディテクトリ直下にresult.txt
を作成していたため、上記の指定でダウンロードができました。
終わりに
AWS CLI で S3 オブジェクトの一覧を出力してみました。
今回は単発で実行できれば良かったので、aws s3 ls での一覧取得で要件にマッチしていました。もう少し定常的に実行が必要、出力結果を他にも活用したい、という場合には S3 インベントリという機能の活用を検討してもよいでしょう。
方式のひとつとして参考になれば幸いです。
以上、 チバユキ (@batchicchi) がお送りしました。