Aws-cli: aws s3 ls - 按修改日期查找文件?

创建于 2015-01-21  ·  87评论  ·  资料来源: aws/aws-cli

你好,
我们希望能够搜索包含数千个(可能会增加到数十万个)对象和文件夹/前缀的存储桶,以查找最近添加或更新的对象。 每天对整个存储桶执行 aws s3 ls 数次,然后对列表进行排序似乎效率低下。 有没有办法简单地请求具有修改时间 <, >, = 某个时间戳的对象列表?

另外,我们是为 aws s3 ls 请求收费一次,还是为请求返回的每个对象收费一次?

github 新手,希望我有足够的知识来贡献实际代码......感谢帮助。

guidance

最有用的评论

@jwieder这无助于用户减少对 s3 的列表调用次数。 假设您每天在一个存储桶中存储大约 1000 篇新闻文章。 然后在客户端希望在默认情况下获取过去 3 天的文章(并且只有在明确请求的情况下才能获取更多文章)。 必须获取自时间开始以来所有文章的列表,比如 100k,需要时间并增加网络成本(因为单个列表调用最多只能返回 1000 个项目)。 能够说“给我一个自 3 天前创建/修改的项目列表”会更好。

所有87条评论

S3 API 不支持此功能,因此仅使用 S3 执行此操作的唯一方法是进行客户端排序。

S3 定价而言,我们使用ListObjects请求一次返回 1000 个对象。 因此,在使用aws s3 ls时,每 1000 个对象将向您收取 LIST 请求的

另一种选择是在 S3 之外存储一个辅助索引,例如 dynamodb。 如果您有任何其他问题,请告诉我。

谢谢

尽管 aws-cli 似乎仍然缺少此功能,但在 bash 中编写脚本非常容易。 例如:

#!/bin/bash
DATE=$(date +%Y-%m-%d)
aws s3 ls s3://bucket.example.com/somefolder/ | grep ${DATE}

@jwieder这无助于用户减少对 s3 的列表调用次数。 假设您每天在一个存储桶中存储大约 1000 篇新闻文章。 然后在客户端希望在默认情况下获取过去 3 天的文章(并且只有在明确请求的情况下才能获取更多文章)。 必须获取自时间开始以来所有文章的列表,比如 100k,需要时间并增加网络成本(因为单个列表调用最多只能返回 1000 个项目)。 能够说“给我一个自 3 天前创建/修改的项目列表”会更好。

确切地!

2016 年 1 月 17 日星期日晚上 11:53,PuchatekwSzortach <
[email protected]> 写道:

@jwieder https://github.com/jwieder这无助于用户减少
对 s3 的列表调用次数。 说你每天存储~1000条新闻
桶中的文章。 然后在客户端想要获得最后 3 篇文章
默认情况下为天(并且仅在明确要求时更多)。 必须取一个
自时间开始以来的所有文章列表,比如 100k,需要时间
并累积网络成本(因为单个列表调用只会返回
到 1000 件)。 能够说“给我一份清单
自 3 天前创建/修改的项目”。


直接回复此邮件或在 GitHub 上查看
https://github.com/aws/aws-cli/issues/1104#issuecomment -172425517。

@PuchatekwSzortach @ChrisSLT你说得对,抱歉我的回答很蹩脚; 我同意这种功能在 aws-cli 中非常有用。 将这个基本功能排除在外并为文件列表收费的组合是非常值得怀疑的。 在 AWS 停止吝啬并引入按文件属性列出之前,这是我使用的另一个想法,它与我的第一个回复更相关:对于需要以这种方式跟踪的文件,文件以时间戳命名. 文件列表存储在本地文本文件中(如果您需要担心大量文件,则可以是 db)。 搜索日期然后涉及打开文件,查找与今天日期匹配的文件名可能如下所示:

读取时 -r 文件名

if [ "$fileName" == "$TODAY" ]; 然后
aws s3 同步 $BUCKETURL /some/local/directory --exclude "*" --include "$fileName"

完成<“$文件”

其中 $FILE 是您的本地文件名索引, $TODAY 是您要搜索的日期。 您需要更改此循环的条件,但希望这可以给您一个想法。

以这种方式进行操作可以免除与列出存储桶中的文件相关的任何费用; 但这也取决于您正在搜索访问本地文件列表的客户端......取决于您的应用程序/系统架构,这可能会使这种方法不可行。 无论如何,希望这对我之前的愚蠢回复有所帮助并再次道歉。

同意并谢谢

2016 年 1 月 19 日,星期二,上午 10:00,Josh Wieder通知@ github.com
写道:

@PuchatekwSzortach https://github.com/PuchatekwSzortach @ChrisSLT
https://github.com/ChrisSLT你说得对,对不起我的蹩脚回复; 和
我同意这种功能在 aws-cli 中非常有用。 这
将这个基本功能排除在外并为文件列表计费
高度怀疑。 直到 AWS 停止吝啬并推出上市
文件属性,这是我使用的另一个更相关的想法
到这个线程然后我的第一个回复:对于需要在此跟踪的文件
方式,文件以时间戳命名。 文件列表存储在本地
文本文件(或者可以是 db,如果你有无数的文件需要担心)。
搜索日期然后涉及打开文件,查找文件名
匹配今天的日期可能看起来像这样:

读取时 -r 文件名

if [ "$fileName" == "$TODAY" ]; 然后
aws s3 同步 $BUCKETURL /some/local/directory --exclude "*" --include
“$文件名”

完成<“$文件”

$FILE 是您的本地文件名索引, $TODAY 是您所在的日期
寻找。 您需要更改此循环的条件,但是
希望这可以给你一个想法。

以这种方式做事可以减轻您与列出相关的任何费用
存储桶中的文件; 但这也取决于您所进行的客户
搜索访问本地文件列表...取决于您
可能采用这种方法的应用程序/系统架构
不可行。 无论如何,希望这对我之前有所帮助并再次道歉
愚蠢的回复。


直接回复此邮件或在 GitHub 上查看
https://github.com/aws/aws-cli/issues/1104#issuecomment -172878454。

有一种方法可以使用 s3api 和 --query 函数来做到这一点。 这是在 OSX 上测试的
aws s3api list-objects --bucket "bucket-name" --query 'Contents[?LastModified>= 2016-05-20 ][].{Key: Key}'
然后,您可以使用 jq 或 grep 进行过滤以使用其他 s3api 函数进行处理。

编辑:不知道为什么他们没有出现,但你必须使用反引号来包围你查询的日期

您是否可以为每一天创建文件夹,这样,您将只访问今天的文件或最多访问昨天的文件夹以获取最新文件。

是的。 虽然您可能会发现简单地为您的密钥使用日期前缀更容易(您不能使用 --bucket 选项查询存储桶名称/文件夹名称组合)。 使用日期前缀将允许您在 cli 中使用 --prefix 标志并加速您的查询,因为 AWS 建议在键名称的开头使用数字或哈希以增加响应时间。

@willstruebing ,您的解决方案仍然不会减少 S3 API 调用的数量、服务器端查询的复杂性或通过网络发送的数据量。 --query参数仅执行客户端 jmespath 过滤。

@kislyuk我完全同意这不能回答效率问题。 但是,我的意图是回答具体问题:

Is there a way to simply request a list of objects with a modified time <, >, = a certain timestamp?

这个基本问题是我如何结束这个线程,所以我认为包含一个答案是合理的。 该问题标记为“aws s3 ls - 按修改日期查找文件?”。

我很想听听任何人对问题效率部分的想法,因为我自己没有一个想法,而且仍然很好奇。

#for i in s3cmd ls | awk {'print $3'} ; 做 aws s3 ls $i --recursive ; 完成 >> s3-full.out

AWS 返回文件的默认设置是什么? 它是按字母顺序返回它们,还是按最近修改的顺序返回它们,或者当您请求第一批 1000 个文件名时使用的标准是什么?

我同意您在请求文件时可以使用某种过滤器(按日期、按名称等排序)……这绝对是一个缺失的功能。 :(

我同意这种过滤应该是服务器端的,并且是基本需求。

+1 用于服务器端查询/过滤

+1 用于服务器端过滤

确实仍然非常需要,+1

同意@chescales和其他人,+1 到服务器端过滤

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

这怎么不是一个功能?

+100000

+1e999

+1

+1

+1

+1

+1

+1

+1

+1

+65535

@willstruebing的评论对我

aws s3api list-objects --bucket "mybucket" --prefix "some/prefix" --query "Contents[?LastModified>=`2018-08-22`].{Key: Key}"

哦,没关系 - 我从这个命令观察网络流量后发现所有密钥仍在从 s3 下载,并且 aws cli 正在执行过滤客户端!

+1

+1

+1

+1

--exclude 和 --include 过滤器呢?

!/bin/bash

DATE=$(日期+%Y-%m-%d)
aws s3 ls s3://bucket.example.com/somefolder/ --exclude " " --include

+1

+1

+100 万

+1

+∞

+∞+1

+1

+1

+1

++

+1

+1

+1

+1 :( :(

我认为这是 AWS 定价模型的一部分,超级便宜的存储但需要付费访问。 适用于大文件,但如果您想查询/管理数百万个小文件,则会毁了您。

+1

我想这就是他们创造雅典娜的原因? 在添加一些花里胡哨的同时计费的另一种方式?

+1

+1

+1

我必须列出在两个日期之间修改的 s3 存储桶对象,例如。 2019-06-08 至 2019-06-11

有人知道吗?

aws s3api list-objects --bucket "BUCKET" --prefix "OPTIONAL" --query "Contents[?LastModified>='2019-06-08'][].{Key: Key,LastModified: LastModified}" 2019-06-11之后再用JQ或者你喜欢的工具过滤掉

这并不能消除 API 调用。 这些查询是客户端

在星期二,2019年6月11日,下午2:07 willstruebing [email protected]
写道:

aws s3api list-objects --bucket "BUCKET" --prefix "OPTIONAL" --query
“内容[?LastModified>='2019-06-08'][].{Key: Key,LastModified:
LastModified}”,然后使用 JQ 或您喜欢的工具过滤掉
2019-06-11


您收到此消息是因为您发表了评论。
直接回复本邮件,在GitHub上查看
https://github.com/aws/aws-cli/issues/1104?email_source=notifications&email_token=AABLGMW5AFAU5BUNM7FEMZ3PZ7SV3A5CNFSM4A2VNZ2KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LODMX5H000000000000000000000000003VMZGOZGOZGOZGO-ZOOM7FEMZ3PZ7SV3A5CNFSM4A2VNZ2KYY3PNVWWK3
或静音线程
https://github.com/notifications/unsubscribe-auth/AABLGMVTIZDPPIEUK2CZR6TPZ7SV3ANCNFSM4A2VNZ2A
.

@dmead我完全同意。 但是,目前不存在执行服务器端过滤的功能(我认为这就是为什么有这么多人最终出现在这个特定的帖子上),所以这是我所知道的完成手头任务的唯一解决方法。 您是否有办法在服务器端做到这一点,或者这只是对建议解决方案的观察? 我很想听听关于如何做到这一点并减少 API 调用量的意见。

如果您有时间,我会考虑在 athena 中选择元数据。 一世
我自己没有机会,但这似乎是一个可能的解决方案。

在星期三,2019年6月12日在10:28 AM现在willstruebing [email protected]
写道:

@dmead https://github.com/dmead我完全同意。 然而
目前不存在执行服务器端过滤的功能(我认为
这就是为什么这么多人最终在这个特定的帖子上),所以这就是
我知道的唯一解决方法来完成手头的任务。 你有没有
做服务器端的方法还是这只是对建议的观察
解决方案? 我很想听听关于如何做到这一点并减少数量的意见
API 调用。


你收到这个是因为你被提到了。
直接回复本邮件,在GitHub上查看
https://github.com/aws/aws-cli/issues/1104?email_source=notifications&email_token=AABLGMTQZD6OWVH4KDMSJPLP2EBY7A5CNFSM4A2VNZ2KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LDNNXP20000000000000000000000000000000000000000001000000
或静音线程
https://github.com/notifications/unsubscribe-auth/AABLGMRLA5OYSYGEYNPUY5DP2EBY7ANCNFSM4A2VNZ2A
.

+24

每个人都对此表示赞同,并使用 AWS CLI 对其进行归档无济于事。 AWS CLI 受 S3 约束。 如果您想修复它,请向 S3 团队提交文件而不是工具的 github :P

@mike-bailey 好的,我该怎么做?

如果是我个人,我会提交一张 AWS 票证,以便它到达服务团队。 但我不为 AWS 工作。 我只知道对此发表评论“+1”不会改变。

有一种方法可以使用 s3api 和 --query 函数来做到这一点。 这是在 OSX 上测试的
aws s3api list-objects --bucket "bucket-name" --query 'Contents[?LastModified>= 2016-05-20 ][].{Key: Key}'
然后,您可以使用 jq 或 grep 进行过滤以使用其他 s3api 函数进行处理。

编辑:不知道为什么他们没有出现,但你必须使用反引号来包围你查询的日期

在尝试此答案之前,请确保您拥有最新版本的awscli 。 我升级了
awscli 1.11.47 -> 1.16.220
它做了可怕的客户端过滤,但它起作用了。
+1 用于服务器端过滤。

+1

+1

请阅读线程,+1 没有任何作用

你不能轻易做到这一点,但埋在这些评论中的是以下提示:

 aws s3api list-objects --bucket "bucket-name" --query 'Contents[?LastModified>=`2016-05-20`][].{Key: Key}'

这仍然是客户端,将执行大量请求。

如前所述,它处理它的客户端。 因此,您仍然可能会通过呼叫猛击桶。

过滤应该是服务器端,我认为是基本需求。

这是使用 aws s3 同步的示例,因此仅下载新文件。 它将日志合并到一个日志文件中,并在保存文件之前去除注释。 然后您可以使用 grep 和 things 来获取日志数据。 就我而言,我需要计算特定文件的唯一点击次数。 下面的代码改编自此链接: https ://shapeshed.com/aws-cloudfront-log/ sed 命令也适用于 Mac,与文章中的内容不同。 希望这可以帮助!

aws s3 sync s3://<YOUR_BUCKET> .
cat *.gz > combined.log.gz
gzip -d combined.log.gz
sed -i '' '/^#/ d' combined.log

# counts unique logs for px.gif hits
grep '/px.gif' combined.log | cut -f 1,8 | sort | uniq -c | sort -n -r

# above command will return something like below. The total count followed by the date and the file name.
17 2020-01-02 /px.gif
 9 2020-01-03 /px.gif

我知道这是一个老问题,但在这里留下一个优雅的解决方案:

aws s3api list-objects --output=text --query "Contents[?LastModified >= <DATE_YOU_WANT_TO_START> ].{Key: Key}"

此页面是否有帮助?
0 / 5 - 0 等级