LoginSignup
3

More than 5 years have passed since last update.

S3に格納したcsvファイルのレコード数をCLIから取得する

Last updated at Posted at 2018-12-21

Amazon S3 Select を利用して S3 に格納してある csv ファイルのレコード数を取得してみました。

使い方

レコード内に改行コードが含まれていても、1レコードとしてカウントされます。
KEY_PATHがフォルダなら再帰的に検索してくれます。

$ s3_cnt
Usage: s3_cnt [BUCKET_NAME] [KEY_PATH]

$ s3_cnt hoge-bucket hoge/fuga/
hoge/fuga/test1.csv :          100
hoge/fuga/test2.csv :          1022
hoge/fuga/foo/test3.csv :      100
hoge/fuga/foo/bar/test4.csv :  200

前準備

インストールしておいてください。

スクリプト作成

利用環境

$ cat /etc/system-release
Amazon Linux 2
$ python -V
Python 2.7.14

Python

s3_cnt.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import argparse
import boto3

def get_args():
    parser = argparse.ArgumentParser()

    parser.add_argument("bucket", help="input bucket name", type=str)
    parser.add_argument("key_path", help="input file path", type=str)
    args = parser.parse_args()

    return(args)

def get_s3_response(bucket, path):
    s3 = boto3.client( 's3', 'ap-northeast-1')

    response = s3.select_object_content(
        Bucket              = bucket,
        Key                 = path,
        ExpressionType      = 'SQL',
        Expression          = 'Select COUNT(1) from S3Object s',
        InputSerialization  = {
            'CompressionType': 'NONE',
            'CSV': {
                'FileHeaderInfo'                : 'Use',
                'RecordDelimiter'               : '\n',
                'FieldDelimiter'                : ',',
                'AllowQuotedRecordDelimiter'    : True    # Falseだと改行コードでレコードが分かれる
            }
        },
        OutputSerialization = {
            'CSV': {
                'RecordDelimiter'   : '\n',
                'FieldDelimiter'    : ','
            }
        }
    )
    return(response)

def main():
    args = get_args()

    response = get_s3_response(args.bucket, args.key_path)
    for event in response[ 'Payload' ]:
        if 'Records' in event:
            records = event[ 'Records' ][ 'Payload' ].decode( 'utf-8' )
            print( records )

if __name__ == '__main__':
    main()

Bash

s3_cnt.pys3_cnt.sh は同階層に置いてください。

s3_cnt.sh
#!/bin/bash

if [ $# -ne 2 ]; then
  echo "Usage: $0 [BUCKET_NAME] [KEY_PATH]" 1>&2
  exit 1
fi

FULL_PATH=$(realpath $0)
cd $(dirname $FULL_PATH)

BUCKET_NAME=$1
KEY_PATH=$2

S3_ARRAY=`aws s3 ls $BUCKET_NAME/$KEY_PATH --recursive`

CSV_ARRAY=()
for data in ${S3_ARRAY[@]}; do
    if echo $data | grep -q '.csv' ; then
        RECORD_VAL=`python s3_cnt.py $BUCKET_NAME $data`
        echo -e "$data : \t$RECORD_VAL"
    fi
done

exit 0

シンボリックリンク張る

$ ln -s /usr/local/bin/s3_cnt /path/to/s3_cnt/s3_cnt.sh

以上

参照

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
3