我的AWS S3密钥路径为bucket-name/fo1/fo2/fo3
,其子路径为
bucket-name/fo1/fo2/fo3/fo_1, bucket-name/fo1/fo2/fo3/fo_2, bucket-name/fo1/fo2/fo3/fo_3
,依此类推。我想遍历路径fo_1, fo_2, fo_3 etc.
中的这些键bucket-name/fo1/fo2/fo3
。
我尝试了以下操作,但这不起作用。
s3 = boto3.client('s3')
s3_bucket = 'bucket-name'
prefix = 'fo1/fo2/fo3'
for obj in s3.list_objects_v2(Bucket=s3_bucket, Prefix=prefix, Delimiter='/'):
# Here when I print obj, it's a string with value as 'MaxKeys'
任何帮助将不胜感激!
更新:
s3://bucket-name/
fo1/
fo2/
fo3/
fo_1/
file1
...
fo_2/
file2
...
fo_3/
file1
...
fo_4/
file1
...
...
这是我的结构,我希望在其中获取fo_1,fo_2,fo_3和文件。我想要对象fo3
中的所有内容,而不要包含其他内容。
答案 0 :(得分:2)
关于Amazon S3的第一件事是folders do not exist
。相反,对象以其完整路径存储为Key
(文件名)。
例如,我可以使用AWS Command-Line Interface (CLI)将文件复制到存储桶:
aws s3 cp foo.txt s3://my-bucket/fo1/fo2/fo3/foo.txt
即使文件夹不存在,这仍然可以工作。
为方便人们使用,我们通过通用前缀的概念提供了一组“假装”文件夹。因此,在管理控制台中,文件夹将显示出现在其中。但是,如果该对象随后通过以下方式删除:
aws s3 rm s3://my-buket/fo1/fo2/fo3/foo.txt
结果是文件夹将立即消失,因为它们实际上从未存在!
为了方便起见,一些Amazon S3命令允许您指定Prefix
和Delimiter
。例如,这可以用于仅列出fo3
文件夹中的对象。它实际上只是在列出以Key
开头的fo1/fo2/fo3/
的对象。返回对象的Key
时,它将始终具有该对象的完整路径,因为Key
实际上是的完整路径。 (没有完整的Key
之外的文件名的概念。)
因此,如果要列出fo1
和fo2
和fo3
中的所有文件,则可以列出Prefix
中fo1
的所有文件并接收以fo1/
开头的所有对象,但这将包含在子文件夹中的对象,因为它们的前缀都为fo1/
。
底线:与其考虑老式目录,不如将Amazon S3视为一个平面存储结构。如有必要,您可以使用自己的代码过滤结果。
答案 1 :(得分:0)
您应该检查list_objects_v2()
调用返回的值,以了解正在返回的数据。
CommonPrefixes
的形式返回。import boto3
s3_client = boto3.client('s3', region_name='ap-southeast-2')
s3_bucket = 'my-bucket'
prefix = 'fo1/fo2/fo3/'
response = s3_client.list_objects_v2(Bucket=s3_bucket)
for object in response['Contents']:
if object['Key'].startswith(prefix):
print(object['Key'])
答案 2 :(得分:0)
可能以下代码对您有用。我在寻找类似的东西时扩展了约翰的答案。我基本上重新创建了 os.walk() 行为,你可能更熟悉
import os
import boto3
# function to replicate os.walk behavior
def s3walk( locations,prefix):
# recursively add location to roots starting from prefix
def processLocation( root,prefixLocal,location):
# add new root location if not available
if not prefixLocal in root:
root[prefixLocal]=(set(),set())
# check how many folders are available after prefix
remainder = location[len(prefixLocal)+1:]
structure = remainder.split('/')
#if we are not yet in the folder of the file we need to continue with a larger prefix
if len(structure)>1:
# add folder dir
root[prefixLocal][0].add(structure[0])
#make sure file is added allong the way
processLocation(root, prefixLocal+'/'+structure[0],location )
else:
# add to file
root[prefixLocal][1].add(structure[0])
root={}
for location in locations:
processLocation(root,prefix,location)
return root.items()
if __name__ == "__main__":
s3_client = boto3.client('s3', region_name='eu-west-3')
s3_bucket = 'bucket-name'
prefix = 'fo1/fo2/fo3'
# get list of objects with prefix
response = s3_client.list_objects_v2(Bucket=s3_bucket,Prefix=prefix)
# retrieve key values
locations = [ object['Key'] for object in response['Contents']]
for root, (subdir, files) in s3walk(locations,prefix):
print(root,subdir,files)