适用于 AWS 的 PowerShell:仅列出来自 S3 存储桶的 "folders"?
PowerShell for AWS: List only "folders" from S3 bucket?
是否有任何简单的方法可以使用 PowerShell 仅从 S3 存储桶中获取 "folders" 的列表,而不列出每个对象并仅编写不同路径的编译列表的脚本?我正在处理的存储桶中有数十万个单独的对象,这需要很长时间。
这可能是一个非常愚蠢的问题,如果是这样的话我很抱歉,但我在 Google 或 SO 上找不到任何内容来回答这个问题。我尝试将通配符添加到 Get-S3Object 的 -KeyPrefix 和 -Key 参数,但无济于事。这是唯一一个似乎能够完成我所追求的事情的 cmdlet。
毫无意义的背景故事:我只是想确保将文件传输到正确的现有文件夹。我是签约第三方,所以我没有控制台登录权限,也不是维护 AWS 账户的人。
我知道使用 Java 和 C# 以及其他语言是可能的,但我正在 PS 中做与这个相当简单的项目相关的所有其他事情,并希望能够坚持下去.
提前致谢。
您可以在存储桶中使用 AWS Tools For PowerShell to list objects (via Get-S3Object) 并从响应对象中提取公共前缀。
下面是一个递归检索子目录的小库:
function Get-Subdirectories
{
param
(
[string] $BucketName,
[string] $KeyPrefix,
[bool] $Recurse
)
@(get-s3object -BucketName $BucketName -KeyPrefix $KeyPrefix -Delimiter '/') | Out-Null
if($AWSHistory.LastCommand.Responses.Last.CommonPrefixes.Count -eq 0)
{
return
}
$AWSHistory.LastCommand.Responses.Last.CommonPrefixes
if($Recurse)
{
$AWSHistory.LastCommand.Responses.Last.CommonPrefixes | % { Get-Subdirectories -BucketName $BucketName -KeyPrefix $_ -Recurse $Recurse }
}
}
function Get-S3Directories
{
param
(
[string] $BucketName,
[bool] $Recurse = $false
)
Get-Subdirectories -BucketName $BucketName -KeyPrefix '/' -Recurse $Recurse
}
此递归函数依赖于在每次迭代时更新 KeyPrefix,以检查传递给它的每个 KeyPrefix 中的子目录。通过将定界符设置为 '/'
,在第一次出现定界符之前与 KeyPrefix 字符串匹配的键将在 $AWSHistory 的最后一个响应中滚动到 CommonPrefixes 集合中。
仅检索 S3 存储桶中的顶级目录:
PS C:/> Get-S3Directories -BucketName 'myBucket'
检索 S3 存储桶中的所有目录:
PS C:/> Get-S3Directories -BucketName 'myBucket' -Recurse $true
这将 return 一个字符串集合,其中每个字符串都是一个公共前缀。
示例输出:
myprefix/
myprefix/txt/
myprefix/img/
myotherprefix/
...
$objects = Get-S3Object -BucketName $bucketname -ProfileName $profilename -Region $region
$paths=@()
foreach($object in $objects)
{
$path = split-path $object.Key -Parent
$paths += $path
}
$paths = $paths | select -Unique
write-host "`nNumber of folders "$paths.count""
Write-host "$([string]::join("`n",$paths)) "
此版本的 Powershell 在单个 S3 存储桶中迭代超过 1000 个密钥(aws 仅限制 API get-S3object 的 1000 个密钥,因此我们需要一个 while-loop 来获取超过 1000 个密钥,也就是文件夹)
输出生成为 csv 后,记得在 Excel 中对重复项进行排序以删除重复项(PS,任何人都可以协助对重复项进行排序,因为我认为我的脚本不能很好地处理重复项)
#Main-Code
$keysPerPage = 1000 #Set max key of AWS limit of 1000
$bucketN = 'testBucket' #Bucketname
$nextMarker = $null
$output =@()
$Start = "S3 Bucket Name : $bucketN"
$End = "- End of Folder List -"
Do
{
#Iterate 1000 records per do-while loop, this is to overcome the limitation of only 1000 keys retrieval per get-s3object calls by AWS
$batch = get-s3object -BucketName $bucketN -Maxkey $keysPerPage -Marker $nextMarker
$batch2 = $batch.key | % {$_.Split('/')[0]} | Sort -Unique
$output += $batch2
$batch2
$nextMarker= $AWSHistory.LastServiceResponse.NextMarker
} while ($nextMarker)
#Output to specific folder in a directory
$Start | Out-file C:\Output-Result.csv -Append
$output | Out-file C:\Output-Result.csv -Append
$End | Out-file C:\Output-Result.csv -Append
接受的答案是正确的,但有一个缺陷。如果你有一个包含许多“文件夹”(超过 1000 个)的大桶,你将只能通过使用以下方式获得最后 1000 个前缀:
$AWSHistory.LastCommand.Responses.Last.CommonPrefixes
AWS 以 1000 个增量批处理响应。如果你看
$AWSHistory.LastCommand.Responses.History
您将看到多个条目。不幸的是,默认情况下只有 5 个。
您可以使用 Set-AWSHistoryConfiguration 函数更改该行为。
要增加历史响应的数量,请使用 -MaxServiceCallHistory 参数。
Set-AWSHistoryConfiguration -MaxServiceCallHistory 20
这将存储下一个(和所有后续)命令的最后 20 个服务调用。
使用上述配置,您最多可以从一个文件夹中检索 20000 个子文件夹。
要检索所有文件夹,请执行以下操作:
$subFolders = ($AwsHistory.LastCommand.Responses.History).CommonPrefixes
注意:增加配置参数会占用更多内存。
是否有任何简单的方法可以使用 PowerShell 仅从 S3 存储桶中获取 "folders" 的列表,而不列出每个对象并仅编写不同路径的编译列表的脚本?我正在处理的存储桶中有数十万个单独的对象,这需要很长时间。
这可能是一个非常愚蠢的问题,如果是这样的话我很抱歉,但我在 Google 或 SO 上找不到任何内容来回答这个问题。我尝试将通配符添加到 Get-S3Object 的 -KeyPrefix 和 -Key 参数,但无济于事。这是唯一一个似乎能够完成我所追求的事情的 cmdlet。
毫无意义的背景故事:我只是想确保将文件传输到正确的现有文件夹。我是签约第三方,所以我没有控制台登录权限,也不是维护 AWS 账户的人。
我知道使用 Java 和 C# 以及其他语言是可能的,但我正在 PS 中做与这个相当简单的项目相关的所有其他事情,并希望能够坚持下去.
提前致谢。
您可以在存储桶中使用 AWS Tools For PowerShell to list objects (via Get-S3Object) 并从响应对象中提取公共前缀。
下面是一个递归检索子目录的小库:
function Get-Subdirectories
{
param
(
[string] $BucketName,
[string] $KeyPrefix,
[bool] $Recurse
)
@(get-s3object -BucketName $BucketName -KeyPrefix $KeyPrefix -Delimiter '/') | Out-Null
if($AWSHistory.LastCommand.Responses.Last.CommonPrefixes.Count -eq 0)
{
return
}
$AWSHistory.LastCommand.Responses.Last.CommonPrefixes
if($Recurse)
{
$AWSHistory.LastCommand.Responses.Last.CommonPrefixes | % { Get-Subdirectories -BucketName $BucketName -KeyPrefix $_ -Recurse $Recurse }
}
}
function Get-S3Directories
{
param
(
[string] $BucketName,
[bool] $Recurse = $false
)
Get-Subdirectories -BucketName $BucketName -KeyPrefix '/' -Recurse $Recurse
}
此递归函数依赖于在每次迭代时更新 KeyPrefix,以检查传递给它的每个 KeyPrefix 中的子目录。通过将定界符设置为 '/'
,在第一次出现定界符之前与 KeyPrefix 字符串匹配的键将在 $AWSHistory 的最后一个响应中滚动到 CommonPrefixes 集合中。
仅检索 S3 存储桶中的顶级目录:
PS C:/> Get-S3Directories -BucketName 'myBucket'
检索 S3 存储桶中的所有目录:
PS C:/> Get-S3Directories -BucketName 'myBucket' -Recurse $true
这将 return 一个字符串集合,其中每个字符串都是一个公共前缀。
示例输出:
myprefix/
myprefix/txt/
myprefix/img/
myotherprefix/
...
$objects = Get-S3Object -BucketName $bucketname -ProfileName $profilename -Region $region
$paths=@()
foreach($object in $objects)
{
$path = split-path $object.Key -Parent
$paths += $path
}
$paths = $paths | select -Unique
write-host "`nNumber of folders "$paths.count""
Write-host "$([string]::join("`n",$paths)) "
此版本的 Powershell 在单个 S3 存储桶中迭代超过 1000 个密钥(aws 仅限制 API get-S3object 的 1000 个密钥,因此我们需要一个 while-loop 来获取超过 1000 个密钥,也就是文件夹) 输出生成为 csv 后,记得在 Excel 中对重复项进行排序以删除重复项(PS,任何人都可以协助对重复项进行排序,因为我认为我的脚本不能很好地处理重复项)
#Main-Code
$keysPerPage = 1000 #Set max key of AWS limit of 1000
$bucketN = 'testBucket' #Bucketname
$nextMarker = $null
$output =@()
$Start = "S3 Bucket Name : $bucketN"
$End = "- End of Folder List -"
Do
{
#Iterate 1000 records per do-while loop, this is to overcome the limitation of only 1000 keys retrieval per get-s3object calls by AWS
$batch = get-s3object -BucketName $bucketN -Maxkey $keysPerPage -Marker $nextMarker
$batch2 = $batch.key | % {$_.Split('/')[0]} | Sort -Unique
$output += $batch2
$batch2
$nextMarker= $AWSHistory.LastServiceResponse.NextMarker
} while ($nextMarker)
#Output to specific folder in a directory
$Start | Out-file C:\Output-Result.csv -Append
$output | Out-file C:\Output-Result.csv -Append
$End | Out-file C:\Output-Result.csv -Append
接受的答案是正确的,但有一个缺陷。如果你有一个包含许多“文件夹”(超过 1000 个)的大桶,你将只能通过使用以下方式获得最后 1000 个前缀:
$AWSHistory.LastCommand.Responses.Last.CommonPrefixes
AWS 以 1000 个增量批处理响应。如果你看
$AWSHistory.LastCommand.Responses.History
您将看到多个条目。不幸的是,默认情况下只有 5 个。 您可以使用 Set-AWSHistoryConfiguration 函数更改该行为。
要增加历史响应的数量,请使用 -MaxServiceCallHistory 参数。
Set-AWSHistoryConfiguration -MaxServiceCallHistory 20
这将存储下一个(和所有后续)命令的最后 20 个服务调用。
使用上述配置,您最多可以从一个文件夹中检索 20000 个子文件夹。
要检索所有文件夹,请执行以下操作:
$subFolders = ($AwsHistory.LastCommand.Responses.History).CommonPrefixes
注意:增加配置参数会占用更多内存。