【问题标题】:How to get the sorted list from aws s3 bucket in an array如何从数组中的aws s3存储桶获取排序列表
【发布时间】:2016-01-16 11:52:28
【问题描述】:

我正在尝试使用 boto 从 aws s3 存储桶中获取对象列表。该列表由两个不同列表的共同元素组成。我希望这个列表按对象的“last_modified”从 S3 存储桶中按升序排序。意思是,我希望旧对象(基于日期)在我的列表中排在第一位。所以,我正在尝试准备这样的 5 个元素的列表。我想获取此列表并仅处理属于此列表的那些文件,并最终删除这些文件并以相同的方式拾取下一个包含 5 个元素的列表。

这是存储桶层次结构:-

//ship-my-data/outputs/444556677788.tar.gz
//ship-my-data/outputs/444556677788.tar.gz
//ship-my-data/outputs/345345345353.tar.gz

//ship-my-data/outputs1/ctrlFiles/ 444556677788.ctrl.tar.gz
//ship-my-data/outputs1/ctrlFiles/ 123222333444.ctrl.tar.gz
//ship-my-data/outputs1/ctrlFiles/ 769797977979.ctrl.tar.gz

我想从上述两个文件夹(即outputs1ctrlFiles 文件夹中)列出常见元素。

这是我的代码:

bucket = LogShip._aws_connection.get_bucket(aws_bucket_to_download) #Connecting to AWS s3 bucket

bucket_list_ctrl = bucket.list(prefix='outputs/ctrlFiles/', delimiter='/') #get the bucket list for control files.
ctrl_list = sorted(bucket_list_ctrl, key=lambda item1: item1.last_modified) # sort the list by last_modified date.

bucket_list_tar = bucket.list(prefix='outputs/', delimiter='/') #get the list for tar files.
tar_list = sorted(bucket_list_tar, key=lambda item2: item2.last_modified) #suppose to get the bucket list, but throwing an error #AttributeError: 'Prefix' object has no attribute 'last_modified'""

for item_c in ctrl_list:
    ctrlName = str(item_c.name).split("/")[2].replace(".ctrl.tar.gz","") # cotrol file name: 1444447203130120001
    for item_t in bucket_list_tar:
        tarName = str(item_t.name).split("/")[1].replace(".tar.gz","") #tar file name: 1444447203130120001
    #now from above two lists I want to prepare a master list of an common elements which is pick up only 5 elements to proceed further.
    j = 5
    while j <= 5:
        for elem in ctrlName:
            for elem in tarName:
                master_list.append(elem)
                j=j+1
            print master_list

输出:

['c', 't', 'r', 'l', 'F', 'i', 'l', 'e', 's', 'c', 't', 'r', 'l', 'F', 'i', 'l', 'e', 's', 'c', 't', 'r', 'l', 'F', 'i', 'l', 'e', 's', 'c', 't', 'r', 'l', 'F', 'i', 'l', 'e', 's', 'c', 't', 'r', 'l', 'F', 'i', 'l', 'e', 's', 'c', 't', 'r', 'l', 'F']

预期输出:

[444556677788, 123222333444]

谁能帮我理解我在哪里犯了错误?

【问题讨论】:

  • 您在两个循环中重复使用elem。你为什么要做“5 个元素的列表”?它循环遍历字符串而不是字符串列表。
  • @JohnRotenstein:谢谢!

标签: arrays python-2.7 sorting amazon-s3 boto


【解决方案1】:

我不确定你为什么要以五人一组的方式做事,所以这段代码一次匹配所有文件:

import boto
import re

conn = boto.connect_s3('REGION')

bucket = conn.get_bucket('BUCKETNAME')

list = bucket.list()

# Get two lists of files
bucket_list_ctrl = bucket.list(prefix='outputs/ctrlFiles/', delimiter='/')
bucket_list_tar  = bucket.list(prefix='outputs/', delimiter='/')

# Extract filenames and modified date
pattern = re.compile('.*?(\d+).*?')
ctrl_files = [(pattern.match(obj.name).group(1), obj.last_modified) for obj in bucket_list_ctrl]
list_files = [pattern.match(obj.name).group(1) for obj in bucket_list_tar if obj.name.endswith('gz')]

# Find filenames that match both
both = [obj for obj in ctrl_files if obj[0] in list_files]

# Give sorted result
result = [f[0] for f in sorted(both, key=lambda obj: obj[1])]

【讨论】:

  • 嗨,约翰,很高兴收到您的来信。感谢您的解决方案。我想在 5 人一组中做事的原因是。我正在尝试处理的这些单个文件的大小超过 1GB。我正在下载这些文件并提供给另一个蒸汽。因此,超过 5 个这么大的文件可能会在下游产生空间问题和其他处理问题。这就是为什么我想在每次运行时处理 5 个文件。
  • 我试过你上面的代码得到一个错误...Traceback (most recent call last): File "/Users/GitRepos/1015/log_ship_dropbox_run.py", line 137, in &lt;module&gt; ctrl_files = [(pattern.match(obj.name).group(1), obj.last_modified) for obj in bucket_list_ctrl] AttributeError: 'NoneType' object has no attribute 'group' Process finished with exit code 1
  • 可能无法找到模式。pattern = re.compile('.*?(\d+).*?') 到底在做什么?
  • 它正在提取数字,这是您想要的文件名的一部分。如果手动创建了一个目录,它可能会失败,该目录会在 S3 存储桶列表中返回但不是文件。您应该能够围绕它编写代码。
  • 谢谢约翰。让我尝试围绕它编写代码。再次感谢!
猜你喜欢
  • 1970-01-01
  • 2020-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-15
  • 2019-02-17
  • 2018-10-11
  • 2020-05-26
相关资源
最近更新 更多