【问题标题】:Get last modfied file from AWS S3 bucket in R从 R 中的 AWS S3 存储桶获取最后修改的文件
【发布时间】:2018-01-18 10:46:37
【问题描述】:

我有一个使用 API 数据实时更新的 S3 存储桶。文件以 .XXX 格式保存,其中 xxx 为 1...n。

我的 R 脚本需要能够获取最新文件并将它们添加到分析数据框中。到目前为止,我一直在使用 aws.s3 包。设置环境密钥/访问密钥后:

mybucket <- get_bucket("mybucket1")

返回一个包含 1000 个元素(可能更多)的 s3 对象,看起来每个对象都有 Contents:list if 7,其中一个是 $LastModified。如何获取上次修改文件的名称?

Mybucket     Large s3_bucket (1000 elements, 2.1Mb)
contents:List of 7
..$ Key : chr "folder1"
..$ LastModified: chr "2018-01-16T09:58:47.000Z"
..$ ETag : chr "\" nnnnnnnnnnn\""
etc (.. $Owner, $Storage class, $bucket, $-attr)
contents: List of 7
..$ Key : chr "folder1/file.1
..$ LastModified: chr "2018....etc"
..$ ETag : chr "...etc..."
etc....
contents: List of 7
etc.....

实际上是“文件”之后的数字。我需要的(在本例中为 1)。

经过实验,我认为通过 RCurl 使用 CLI 命令会是一个更好的选择。

aws s3 ls s3://mybucket --recursive | grep APIdata@symbol=XXX&interval=5.1*

这让我非常接近,但该命令省略了“&interval=5.1*”,因此它返回了所有带有“APIdata@symbol=XXX*”的对象

【问题讨论】:

  • 请在您的问题中添加一些示例数据(例如前 n 个元素),以便我们更容易回答。谢谢 :-)
  • 我更新了环境窗口中的描述。谢谢!
  • aws.s3 pkg 文档对回答您问题的数据类型不是很清楚。您能否将dput(Mybucket[1:3]) 的输出添加到问题中(但请先匿名内容!)因为我需要知道确切的数据类型和属性才能回答您的问题。但是:基本上它看起来像是将所有内容转换为 data.frame,转换 LastModifiedDate,对其进行排序并获取最后一个条目......
  • 它们都是 JSON 文件,扩展名范围为 .1,.2,.3.....x。我特别试图避免将 30,000 个文件的整个文件列表调用到 R 中,并试图将其限制为 .1*,因为这会给我 0.1、0.10-19、0.100-199 以及所有数千个范围。
  • 尽量减少网络流量是个好主意,请务必在您的问题中提及此类非功能性需求以获得准确答案。我认为您需要在服务器端有一个 shell 脚本来过滤最新的文件,这不是 R 问题,但这确实为您提供了get_bucket 提供的所有其他信息

标签: r amazon-web-services amazon-s3


【解决方案1】:

最简单的方法是使用系统命令:

currentfile <- system("aws s3 ls s3://bucket/folder --recursive | grep 'file.16' | sort | tail -n 1 | awk '{print $4}'", intern=TRUE)

grep 抓取存在“file.16”的文件,这大大缩小了搜索范围,因为当前文件列表位于 1600 年代。 Intern=TRUE 保存响应,在这种情况下将其作为字符串保存在 'currentfile' 中。按修改日期排序、拖尾和打印 $4 订单文件,取最后修改的第 4 列(名称)。

供参考:Downloading the latest file in an S3 bucket using AWS CLI?

【讨论】:

    【解决方案2】:

    我认为您的问题与 AWS S3 无关,我会将其归类为 如何从列表列表中创建 data.frame,并且对此已有答案,例如。 g.:

    R list of lists to data.frame

    我的解决方案使用 data.table 包中的方便 rbindlist

    我不得不猜测Mybucket 的数据类型,但解决方案可能如下所示:

    # https://cran.r-project.org/web/packages/aws.s3/aws.s3.pdf
    # get_bucket: returns a list of objects in the bucket (with class “s3_bucket”)
    library(data.table)
    library(lubridate)
    
    # my personal assumption of the output of "get_bucket" is list of list (I have no S3 at hand to verify this)
    Mybucket <- list(  list(Key = "folder1/file.1", LastModified = "2018-01-16T09:58:47.000Z", ETag = "\" nnnnnnnnnnn\"")
                     , list(Key = "folder2/file.2", LastModified = "2018-01-16T08:58:47.000Z", ETag = "xyz"))
    
    dt <- rbindlist(Mybucket)  # convert into a data.table (enhanced data.frame)
    
    dt[, LastModAsDate := ymd_hms(LastModified)]  # add a data column
    
    dt.most.recent <- dt[order(-dt$LastModAsDate),][1]  # order by date descending, then pick the top-most row
    

    导致

    > dt.most.recent
                  Key             LastModified           ETag       LastModAsDate
    1: folder1/file.1 2018-01-16T09:58:47.000Z " nnnnnnnnnnn" 2018-01-16 09:58:47
    

    请注意,日期转换可能会降低精度(毫秒),但无论如何都会勾勒出整体解决方案...

    要提取文件扩展名中包含的数字,请使用:

    tools::file_ext(dt.most.recent$Key)
    # [1] "1"
    

    【讨论】:

    • 感谢您的建议,但为了澄清一下,我特别想避免将 30k 文件的整个列表带入 R。我认为通过 RCurl 调用 CLI 会是一个更好的选择,但没有 - -include --exclude 选项:aws s3 ls s3://my-bucket/ 命令。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-19
    • 2020-12-16
    • 2020-06-15
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    相关资源
    最近更新 更多