0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Get-S3ObjectV2で指定フォルダ直下のフォルダ一覧を取得

Posted at

AWS Tools for PowerShellで、AWS S3の指定フォルダ直下のフォルダを取得したかった。例えばバケット内に次のような構成があるとして…

AWSLogs/
  +-- o-xxx9xxx9xx/
        +-- 000000000000/
        |     +-- ap-northeast-1/
        |     :
        +-- 111111111111/
        :

AWSLogs/o-xxx9xxx9xx/ 直下の 000000000000/ 111111111111/ というリストを得たい。

結論としては、以下のようにすればいい。

$objects = Get-S3ObjectV2 -BucketName $bucketName -Prefix "AWSLogs/o-xxx9xxx9xx/" -Delimiter "/" -Select CommonPrefixes

$objects には以下が格納されている。型は文字列。

AWSLogs/o-xxx9xxx9xx/000000000000/
AWSLogs/o-xxx9xxx9xx/111111111111/
 :

直下のものの取得: -Delimiter "/" オプション

-Prefix でのプレフィックス指定だけだと、内部的には「フルパスがこれに前方一致する」ものをすべて返してしまうので、「指定ディレクトリ以下のファイルを再帰的にリストアップする」ような動作になる。期待動作と違ったり、該当するものが多いと時間がかかったり上限(1度に1,000件まで)に引っかかったりする。

直下のもの=プレフィックスから次の / までの要素だけを取得するには、 -Delimiter "/" を指定する。

$objects = Get-S3ObjectV2 -BucketName $bucketName -Prefix "AWSLogs/o-xxx9xxx9xx/" -Delimiter "/"

フォルダーの取得:-Select CommonPrefixes オプション

Get-S3ObjectV2 をそのまま実行すると、オブジェクト(ファイル的なもの)だけが返される。ディレクトリに相当するものはCommonPrefixと呼ばれており、取得したい時には -Select CommonPrefixes を付ける。

$objects = Get-S3ObjectV2 -BucketName $bucketName -Prefix "AWSLogs/o-xxx9xxx9xx/" -Delimiter "/" -Select CommonPrefixes

フォルダ相当のものが、文字列型で返される。

PS> $objects[0]
AWSLogs/o-xxx9xxx9xx/000000000000/
PS> $objects[0].GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object

参考

以下を参考にした。

AWS CLIやSDKでのS3利用経験があれば、わりとすぐに「 -Delimiter "/" 使うだけだろ、悩むとこある?」と思う気がする。でも実際には上述の通り「オブジェクトだけが返さ、CommonPrefixは返されない」ということになる。ここの解決方法を、このGitHubイシューで知った。

まず「パイプライン処理と $AWSHistory - AWS Tools for PowerShell」によれば、AWS Tools for PowerShellは次の挙動をする。

  • コレクションを返すコマンドレットは、コレクション内のオブジェクトが返される。
  • 内部で実行したAWS APIの結果値が、上のコレクションの他にページング制御フィールドではない追加フィールドを含む場合は、$AWSHistory セッション変数に記録される。

つまり、APIの実行結果そのままではない。Get-S3ObjectV2コマンドレットであれば、Synopsysに書かれているように内部では S3 ListObjectsV2 APIを実行している。その結果値は以下で解説されている通り Contents に格納されたオブジェクトのコレクションとは別に、 CommonPrefixes にCommonPrefixが格納されている。

で、Get-S3ObjectV2コマンドレットはそのAPIの実行結果から Contents だけを抜き出されて返し、CommonPrefixはたぶん(確認してないけど)$AWSHistory変数に格納する。前記のGithub Issueでは…

「そういういものだから」(2021.10.16
「いやもっとわかりやすく」(2021.10.18
-Select CommonPrefixesでもイケるっぽいけど、せめてドキュメントのExampleに入れようよ」(2022.5.13
「わかったよドキュメント改定するよ」(2023.04.08

…みたいなやり取りしてて、これ読んで-Select CommonPrefixesでイケるのがわかって助かったけど、最後のコメントから1年余り経過した2024年5月10日現在、ドキュメントは改定されてないですよね?

0
0
0

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?