この記事は
YAMAP エンジニア Advent Calendar 2020 の六日目になる予定です。
tl;dr
ギョームにて、S3 バケットに保存されている画像ファイルのファイルサイズや大きさの一覧が欲しいというリクエストを頂きましたので、AWS CLI と grep や awk 等のトラディショナルなツール、たまに Python スクリプトを駆使してリストアップしてみたのでメモしておきます。
尚、本記事で登場するツールのバージョンについては、以下の通りです。
$ sw_vers ProductName: Mac OS X ProductVersion: 10.15.7 BuildVersion: 19H15 $ aws --version aws-cli/2.1.1 Python/3.9.0 Darwin/19.6.0 source/x86_64 $ docker run --rm -t -i python:buster python --version Python 3.9.0
尚、ここで書いてあるコマンドやシェルスクリプトは、あくまでも一例であり、他の実装があれば、是非、コメント等いただけると嬉しいです。
ファイルサイズ
シンプルに一覧を取得
# # * --recursive: 再帰的にリストを出力する # * --human: ファイルサイズに単位を付与して出力する # * --sum: サマリー (オブジェクト個数と合計サイズ) を出力する # $ aws s3 ls s3://${BUCKET}/${OBJECT_PATH}/ --recursive --human --sum
以下のように出力されます。
... 2020-09-27 18:09:07 527.4 KiB /path/to/image1.png 2020-09-27 18:09:07 1.0 MiB /path/to/image2.png Total Objects: 8436 Total Size: 1.6 GiB
こちらでも一覧を取得できます。
fish> env AWS_PAGER="" aws s3api list-objects-v2 --bucket=${BUCKET} \ --query='Contents[].[LastModified, Size, Key]' --output=text
以下のように出力されます。
--human
相当のオプションが存在していないことが残念です。2 列目がオブジェクトのサイズで、単位は bytes
となります。
2020-09-27T09:09:07+00:00 540036 /path/to/image1.png 2020-09-27T09:09:07+00:00 1055619 /path/to/image2.png
env AWS_PAGER=""
としているのは、AWS CLI v2 はデフォルトでページャーが有効になっているので、これを一時的に無効にしています。
MiB 及び GiB サイズの一覧を取得
MiB と GiB サイズの一覧を取得したい場合には、以下のように実行します。
$ aws s3 ls s3://${BUCKET}/${OBJECT_PATH}/ --recursive --human --sum \ | egrep 'MiB|GiB' \ | grep -v 'Total Size:' \ | sort -k3 -r
また、容量が大きい順にソートして出力するように調整しています。
以下のように出力されます。
2020-05-08 15:55:40 26.9 MiB /path/to/image1.png 2020-11-19 23:18:22 16.5 MiB /path/to/image2.png ... 2020-08-19 21:32:30 1.0 MiB /path/to/image099.png 2020-08-19 21:33:38 1.0 MiB /path/to/image100.png
100KiB 以下の一覧を取得
100KiB 以上のオブジェクトの一覧を取得した場合には、以下のように実行します。
aws s3 ls s3://${BUCKET}/${OBJECT_PATH}/ --recursive --human --sum \ | egrep 'KiB' \ | grep -v 'Total Size:' \ | sort -k3 -r \ | awk '$3 < 100.0{print}'
以下のように出力されます。
2020-09-02 14:08:18 99.9 KiB /path/to/image1.png 2020-11-20 18:13:43 99.8 KiB /path/to/image2.png ... 2020-05-08 15:41:50 1.3 KiB /path/to/image099.png 2019-10-10 17:27:04 1.3 KiB /path/to/image100.png
awk
で awk '$3 < 100.0{print}'
こう書くことで、対象列の数値比較が出来ることを初めて知りました。
大きさ (縦横)
残念ながら
AWS の API で取得する方法を見つけることが出来ませんでしたので、Python と boto3 を使うことにしました。
雑な Python スクリプト
以下のように雑な Python スクリプトを書きました。このスクリプトを適当なファイル名で保存します。(今回は check.py としました。)
from PIL import Image import boto3 s3 = boto3.client('s3') bucket = 'YOUR-BUCKET-NAME' f = open('IMAGE-LIST') lines = f.readlines() for line in lines: key = line.replace('\n' , '') local = '/tmp/' + line.split('/')[-1] s3.download_file(bucket, key, local) im = Image.open(local) width, height = im.size print("key: %s, height: %s, width: %s" % (key, height, width))
画像ファイルの縦、横サイズを取得する為、Pillow というライブラリを利用しました。
また、IMAGE-LIST
は、以下のコマンドで取得したオブジェクトの一覧が記載されたファイルとなります。
$ aws s3 ls s3://${BUCKET}/${OBJECT_PATH}/ --recursive --human --sum | awk '{print $5}' > IMAGE-LIST $ cat IMAGE-LIST /path/to/image1.png /path/to/image2.png ... /path/to/image099.png /path/to/image100.png
一旦、この Python スクリプトを使って、全ての画像ファイルの縦横サイズを取得します。
$ docker run -t -i --rm -v $PWD:/work python:buster bash docker> pip install Pillow boto3 docker> python check.py key: /path/to/image1.png, height: 150, width: 150 key: /path/to/image2.png, height: 576, width: 1024 ...
いい感じです。縦 (height
) と横 (width
) とオブジェクトキー (ファイル名) が出力されました。
以上
こういう細かいけど、なんとなくエンジニアリングな作業が大好きです。また、上記以外にも様々な実装がありそうなので、ワクワク感もたまりませんな。
以上、素敵な S3 バケットライフをお過ごし下さい。