経緯
S3バケット内のオブジェクト(ファイル)について、名前・最終更新日・サイズを取得してCSVファイルに出力したい。
Pythonでスクリプトを書いていく。不慣れなため無駄が多いかと思うが、ご容赦を。
参考:AWS Lambda Python S3でフォルダ以下のファイル一覧を取得する
スクリプト作成
以下の構成において、xxx配下のファイル一覧(名前、最終更新日、サイズ)を取得する。
また、オブジェクトは名前(ooooo)で絞って出力する。
s3://aaa.backup/xxx/ooooo
aaa.backup:バケット
xxx:プリフィックス
ooooo**:オブジェクト
出力するCSVの中身は以下のようにしたい。
見出し: Name,Data,Size
データ: oooooabcd,[JST]2022/01/10 12:05:10,20.5 KB
オブジェクトキーの出力
参考:Boto 3 で Amazon S3 上の key を取得する方法、実装例、注意点
Boto3でS3 Buckets上の情報を取得するときは、list_objects() を使用する。
今回は対象が多いため、プリフィックスとオブジェクト名の一部を指定して条件を絞る。
最終更新日をJSTに変更
S3の最終更新日時(content['LastModified'])はUTCで保存されている。今回はJSTで出力したいため、変換を行う。
参考:PythonでUTCからJSTへの時刻の変換
この方法で行うとS3で保持している最終更新日の最後の6字「+00:00」が邪魔になり、UTCのまま出力されてしまう。
そのため、文字列へ変換して該当文字を削除することでJSTで出力することができる。
- datetimeを使用してJSTへの変換を指定
- 文字列にし、「+00:00」を省く(後方から6文字削除)
- JSTへの時刻の変換
import datetime
def utc_to_jst(timestamp_utc):
datetime_utc = datetime.datetime.strptime(timestamp_utc + "+0000", "%Y-%m-%d %H:%M:%S%z")
datetime_jst = datetime_utc.astimezone(datetime.timezone(datetime.timedelta(hours=+9)))
timestamp_jst = datetime.datetime.strftime(datetime_jst, '%Y-%m-%d %H:%M:%S')
return timestamp_jst
for page in page_iterator:
for content in page['Contents']:
date = content['LastModified']
Last = str(date)
Last = Last[:-6]
print(Last)
print("[JST]" + utc_to_jst(Last))
(結果)
2022/01/10 12:05:10 +00:00
[JST]2022/01/10 12:05:10
オブジェクト名からプリフィックスの表示を除く
そのままオブジェクトキー(content['Key'])を出力すると、プリフィックスを含んだものが出力される。
見にくいため、プリフィックス名を指定してオブジェクト名のみを出力する。
参考:完全一致する文字列を削除: replace()
name = content['Key']
print(name)
print(name.replace('xxx/',''))
(結果)
xxx/oooooabcd
oooooabcd
サイズをKB表示にする
サイズ(content['Size'])をそのまま出力すると、バイトのため大きなサイズの際は見にくい。
また、単位もつけたいため、以下のように記述。
1024で割ってKBへ変換>小数点以下第2位を四捨五入>データ型を文字列に変換>単位をつける
n = content['Size']/1024
Size = round(n,1)
Size = str(Size) + "KB"
print(content['Size'])
print(Size)
(結果)
22837
22.3KB
1000件以上のデータ出力に対応
Python で Amazon S3 バケットの全オブジェクト名を取得するジェネレータ
今回はV2不使用のため不要だったが、使用する際は考慮が要るかも。
CSV出力
Pythonでcsvファイルにデータを書き込みをする基本中の基本
- Excelでも使用したいので文字コードを shift-jis で保存
- ヘッダ行をつける(Name,Date,Size) ※実際のスクリプトでは1度開いてヘッダをつけ、再度開き直してオブジェクトキーなどの入力を行う
- ファイル名がオブジェクト名になるよう変数を設定
import csv
wwith open(Object + '_JST.csv','a',newline='',encoding = "shift-jis") as f:
writer = csv.writer(f)
writer.writerow(["Name","Date","Size"])
with open(Object + '_JST.csv','a',newline='',encoding = "shift-jis") as f:
writer = csv.writer(f)
writer.writerow([content['Key'].replace('xxx/',''),Last,Size])
スクリプト
以下、完成したスクリプト
import boto3
import datetime
import csv
MY_REGION = 'MY_REGION';
MY_BUCKET = 'MY_BUCKET';
TARGET_PATH = 'TARGET_PATH/';
Object = 'Object';
client = boto3.client('s3', region_name=MY_REGION)
paginator = client.get_paginator('list_objects')
# フィルタリング設定
operation_parameters = {
'Bucket': MY_BUCKET,
'Prefix': TARGET_PATH + Object
}
page_iterator = paginator.paginate(**operation_parameters)
# UTCからJSTへの時刻の変換
def utc_to_jst(timestamp_utc):
datetime_utc = datetime.datetime.strptime(timestamp_utc + "+0000", "%Y-%m-%d %H:%M:%S%z")
datetime_jst = datetime_utc.astimezone(datetime.timezone(datetime.timedelta(hours=+9)))
timestamp_jst = datetime.datetime.strftime(datetime_jst, '%Y-%m-%d %H:%M:%S')
return timestamp_jst
# 出力CSVを作成し、ヘッダをつける
with open(Object + '_JST.csv','a',newline='',encoding = "shift-jis") as f:
writer = csv.writer(f)
writer.writerow(["Name","Date","Size"])
for page in page_iterator:
for content in page['Contents']:
# 最終更新日をUTCからJSTへ変更
Last = content['LastModified']
Last = str(Last)
Last = Last[:-6]
Last = utc_to_jst(Last)
# サイズをキロバイトへ変更
n = content['Size']/1024
Size = round(n,1)
Size = str(Size) + "KB"
with open(Object + '_JST.csv','a',newline='',encoding = "shift-jis") as f:
writer = csv.writer(f)
# CSVへ情報出力
writer.writerow([content['Key'].replace('xxx/',''),Last,Size])
(出力結果)
Name,Data,Size
oooooabcd,[JST]2022/01/10 12:05:10,20.5KB
oooooefgh,[JST]2022/01/11 10:03:18,13.2KB
…