https://docs.aws.amazon.com/cli/latest/reference/s3api/list-objects.html
aws s3の仕様は↑こちらで、 これを Net::Amazon::S3 for perl で実装したものが、以下。
大量のファイルでもあっても取得できるポイントは、 perl src内にあるmarkとnext_maker で、 これがページングの役割を担っています。
#!/usr/local/bin/perl use strict; use warnings; use Encode; use Net::Amazon::S3; use Data::Dumper; my $CONF = {aws_s3=> {client=>{ host=> 'ないしょ', aws_access_key_id => 'ないしょ', aws_secret_access_key => 'ないしょ', retry => 1}, bucket=>'ないしょ'}, ls=>{max_keys=>5, # 一度に取得するobj keyの制限 delimiter=>"/", # 不要と思いますが、これがないとs3がis_truncatedを返さない... max_exec=>10, # lsを実行する回数制限 sleep=>2} # やさしく ls }; main( @ARGV ); sub main { my ($kyoten_code) = @_; unless( $kyoten_code ){ return disp_usage(); } my $s3 = Net::Amazon::S3->new(%{$CONF->{aws_s3}->{client}}); $s3->ua( LWP::UserAgent->new(ssl_opts=>{verify_hostname =>0}) ); my $bucket = $s3->bucket($CONF->{aws_s3}->{bucket} ); my $list_opt = {prefix=> $kyoten_code, max_keys => $CONF->{ls}->{max_keys}, delimiter=> $CONF->{ls}->{delimiter} }; my $pre_ls_res = {is_truncated=>1}; my $ls_exec_count = 0; my $obj_keys_size = 0; while($pre_ls_res->{is_truncated} and $ls_exec_count++ < $CONF->{ls}->{max_exec} ){ # 前回の続きから、ls する為、markerをset $list_opt->{marker} = $pre_ls_res->{next_marker}; my $ls_res = $bucket->list($list_opt); $obj_keys_size += scalar(@{$ls_res->{keys}}); for my $obj_info ( @{$ls_res->{keys}} ){ # version idは別途、取得する必要あり my $obj_detail = $bucket->head_key($obj_info->{key}); my $disp_str = join("\t", $obj_info->{key}, $obj_detail->{'x-amz-version-id'} || '', $obj_info->{size}, $obj_info->{etag}, $obj_info->{last_modified}); print "$disp_str\n"; } # 続きがある場合、is_truncated = true ですって $pre_ls_res->{is_truncated} = $ls_res->{is_truncated}; $pre_ls_res->{next_marker} = $ls_res->{next_marker}; sleep($CONF->{ls}->{sleep}); } print "You have $obj_keys_size objects !!\n"; } sub disp_usage { print "Usage: $0 HEIM_KYOTEN_CODE.\n"; } 1;