【问题标题】:copy data from s3 to local with prefix使用前缀将数据从 s3 复制到本地
【发布时间】:2020-03-11 02:13:20
【问题描述】:

我正在尝试使用 aws-cli 将数据从 s3 复制到带有前缀的本地。

但是我在使用不同的正则表达式时遇到了错误。

aws s3 cp s3://my-bucket-name/RAW_TIMESTAMP_0506* . --profile prod

错误:

未找到匹配项:s3://my-bucket-name/RAW_TIMESTAMP_0506*

【问题讨论】:

  • 请提及有关“RAW_TIMESTAMP_0506”的信息,即它是文件名模式、前缀等。
  • @tom 是的,它是前缀。

标签: amazon-web-services amazon-s3 aws-cli


【解决方案1】:
aws s3 cp s3://my-bucket/ <local directory path> --recursive --exclude "*" --include "<prefix>*"

这将只复制具有给定前缀的文件

【讨论】:

  • 是,如果您指定 .然后将内容下载到根目录,而指定 ./path-to-folder 则将内容下载到特定路径!成功了,谢谢..
【解决方案2】:

上面的答案不能正常工作......例如,我在一个目录中按日期有数千个文件,我希望只检索需要的文件......所以我尝试了每个文件的正确版本:

aws s3 cp s3://mybucket/sub /my/local/ --recursive --exclude "*" --include "20170906*.png"

它并没有下载前缀文件,而是开始下载所有内容

然后我尝试了上面的示例:

aws s3 cp s3://mybucket/sub/ . /my/local --recursive --include "20170906*"

它还下载了所有内容...这似乎是 aws cli 的一个持续问题,他们无意修复它...这是我在谷歌搜索时发现的一些解决方法,但它们并不理想.

https://github.com/aws/aws-cli/issues/1454

【讨论】:

  • 使用 --exclude "*" 和你上面的命令应该可以工作。
  • 对于名为 dev20200808.json 的 S3 文件,我尝试过 :: aws s3 cp s3://my-bucket-name/ ./path-to-my-local-folder --exclude "*" --include "*20200808*" --recursive 并且成功了!!我第一次只有--include,以为只会复制匹配的对象,但遗憾的是桶中的所有内容都已复制,然后我使用--exclude--include 使其工作。最后,它似乎首先是 exclude 一切,然后是 include 所需要的 :-) 此外,如果您只提供 . 而不是 ./path-to-my-local-folder,那么文件将被复制到根文件夹。
  • Git 问题的一个很好的解决方法链接:aws s3 ls "s3://bucket/prefix" | awk '{print $4}' | xargs -I % aws s3 cp s3://bucket/% .
【解决方案3】:

aws s3 cp 命令不接受通配符作为文件名(键)的一部分。相反,您必须使用--include--exclude 参数来定义文件名。

发件人:Use of Exclude and Include Filters

目前,不支持在命令的路径参数中使用 UNIX 样式的通配符。但是,大多数命令都有--exclude "&lt;value&gt;"--include "&lt;value&gt;"参数,可以达到预期的效果。这些参数执行模式匹配以排除或包含特定文件或对象。支持以下模式符号。

所以,你会使用类似的东西:

aws s3 cp s3://my-bucket-name/ . --include "RAW_TIMESTAMP_0506*"

【讨论】:

  • 我不认为它在没有 --recursive 标志的情况下工作。我的存储桶中有一个内部目录,我不想从那里复制文件。请建议
  • 正确!要么使用--recursive 标志,所以使用aws s3 sync,其中包括子目录。
  • 该命令根本不起作用。还需要排除,因为--include 本身不排除。
【解决方案4】:

如果您不喜欢静音控制台,您可以通过管道 aws lsawk 并返回到 aws cp

示例

url='s3://my-bucket-name'
prefix='RAW_TIMESTAMP_0506'
aws s3 ls "$url/$prefix" | awk '{system("aws s3 cp '"$url"'/"$4 " .")}'

说明

  • ls 部分非常简单。我正在使用变量来简化和缩短命令。始终将 shell 变量用双引号括起来以防止灾难。
  • awk {print $4} 只会从 ls 输出中提取文件名
  • awk {system("echo " $4")} 会做同样的事情,但它通过调用另一个命令来完成此操作。注意:我没有使用子shell $(...),因为这会在cp 开始之前运行整个ls | awk 部分之前。那会很慢,而且很长一段时间都不会打印任何东西。
  • awk '{system("echo aws s3 cp "$4 " .")}' 会打印出与我们想要的非常接近的命令。注意间距。如果你尝试运行它,你会发现有些地方不太对劲。这将产生 @ @987654333 @之类的命令
  • @ 987654334@是我们想要的。这为文件名增加了路径。仔细观察报价。请记住,我们将 awk 参数包裹在单引号中,因此如果我们想在该参数中使用 shell 变量,我们必须关闭并重新打开引号。
  • @ 987654336@是最终版本。我们只需删除echo 以实际执行 awk 创建的命令。当然,我还用双引号将 $url 变量括起来,因为这是一种很好的做法。

【讨论】:

  • 我并没有被安静所困扰,但是当复制花了很长时间并且令牌最终过期时,我被超时所困扰。我最终做了类似这样的模糊操作,将我想要的文件列表复制到我的笔记本电脑上,然后使用xargs 循环一个一个地复制它们。
  • @tripleee 我很想看看你的 xargs 解决方案!
  • 基本上是aws s3 ls s3://path/to/prefix/ | sed 's%^%s3://path/to/prefix/' &gt;file.txt,然后是xargs -i aws s3 cp {} . &lt;file.txt
  • 这是我最喜欢的终端反馈循环的答案。谢谢!
猜你喜欢
  • 2021-11-27
  • 2021-01-17
  • 2020-10-30
  • 1970-01-01
  • 2013-05-31
  • 1970-01-01
  • 1970-01-01
  • 2018-09-12
  • 1970-01-01
相关资源
最近更新 更多