如何仅显示来自 aws s3 ls 命令的文件?

How to display only files from aws s3 ls command?

我正在使用 aws cli 使用以下命令列出 s3 存储桶中的文件 (documentation):

aws s3 ls s3://mybucket --recursive --human-readable --summarize

此命令给出以下输出:

2013-09-02 21:37:53   10 Bytes a.txt
2013-09-02 21:37:53  2.9 MiB foo.zip
2013-09-02 21:32:57   23 Bytes foo/bar/.baz/a
2013-09-02 21:32:58   41 Bytes foo/bar/.baz/b
2013-09-02 21:32:57  281 Bytes foo/bar/.baz/c
2013-09-02 21:32:57   73 Bytes foo/bar/.baz/d
2013-09-02 21:32:57  452 Bytes foo/bar/.baz/e
2013-09-02 21:32:57  896 Bytes foo/bar/.baz/hooks/bar
2013-09-02 21:32:57  189 Bytes foo/bar/.baz/hooks/foo
2013-09-02 21:32:57  398 Bytes z.txt

Total Objects: 10
   Total Size: 2.9 MiB

然而,这是我想要的输出:

a.txt
foo.zip
foo/bar/.baz/a
foo/bar/.baz/b
foo/bar/.baz/c
foo/bar/.baz/d
foo/bar/.baz/e
foo/bar/.baz/hooks/bar
foo/bar/.baz/hooks/foo
z.txt

如何省略日期、时间和文件大小以便仅显示文件列表?

您不能仅使用 aws 命令来执行此操作,但您可以轻松地将其通过管道传输到另一个命令以删除不需要的部分。您还需要删除 --human-readable 标志以使输出更易于使用,并删除 --summarize 标志以删除末尾的摘要数据。

试试这个:

aws s3 ls s3://mybucket --recursive | awk '{print }'

编辑:考虑文件名中的空格:

aws s3 ls s3://mybucket --recursive | awk '{===""; print [=11=]}' | sed 's/^[ \t]*//'

一个简单的过滤器是:

aws s3 ls s3://mybucket --recursive | perl -pe 's/^(?:\S+\s+){3}//'

这将删除日期、时间和大小。只留下文件的完整路径。它也可以在没有递归的情况下工作,它也应该适用于包含空格的文件名。

简单方法

aws s3 ls s3://mybucket --recursive --human-readable --summarize|cut -c 29-

简单的命令是

aws s3 ls s3://mybucket --recursive --human-readable --summarize |cut -d ' ' -f 8

如果您需要时间戳,只需更新命令字段值即可。

仅对于 file 名称,我发现最简单的是:

aws s3 ls s3://path/to/bucket/ | cut -d " " -f 4

这将在空格 (cut -d " ") 和 return 第四列 (-f 4) 处剪切 returned 输出,这是文件名列表.

将 s3api 与 jq (AWS docu aws s3api list-objects) 一起使用:

这种模式总是递归的。

$ aws s3api list-objects --bucket "bucket" | jq -r '.Contents[].Key'
a.txt
foo.zip
foo/bar/.baz/a
[...]

您可以通过添加前缀来过滤子目录(此处为 foo 目录)。前缀不得以 /.

开头
$ aws s3api list-objects --bucket "bucket" --prefix "foo/" | jq -r '.Contents[].Key'
foo/bar/.baz/a
foo/bar/.baz/b
foo/bar/.baz/c
[...]

jq 选项:

  • -r = 原始模式,输出中没有引号
  • .Contents[] = 获取Contents对象数组内容
  • .Key = 获取每个关键字段(不会产生有效的 JSON 数组,但我们处于原始模式,所以我们不关心)

附录:

您可以使用纯 AWS CLI,但值将由 \x09 = Horizo​​ntal Tab (AWS: Controlling Command Output from the AWS CLI - Text Output Format)

分隔
$ aws s3api list-objects --bucket "bucket" --prefix "foo/" --query "Contents[].Key" --output text
foo/bar/.baz/a   foo/bar/.baz/b   foo/bar/.baz/c   [...]

AWS CLI 选项:

  • --query "Contents[].Key" = 查询内容对象数组并获取里面的每个键
  • --output text = 输出为带有现在引号的制表符分隔文本

根据李光阳评论补充:

带有新行的纯 AWS CLI:

$ aws s3api list-objects --bucket "bucket" --prefix "foo/" --query "Contents[].{Key: Key}" --output text
foo/bar/.baz/a
foo/bar/.baz/b
foo/bar/.baz/c
[...]

我的解决方案

使用 aws cli 递归地仅列出文件。

aws s3 ls s3://myBucket --recursive | awk 'NF>1{print }' | grep .

grep . - 清除空行。


示例:aws s3 ls s3://myBucket

                           PRE f5c10c1678e8484482964b8fdcfe43ad/
                           PRE f65b94ad31734135a61a7fb932f7054d/
                           PRE f79b12a226b542dbb373c502bf125ffb/
                           PRE logos/
                           PRE test/
                           PRE userpics/
2019-05-14 10:56:28       7754 stage.js

解决方案:aws s3 ls s3://myBucket --recursive | awk 'NF>1{print }' | grep .

stage.js

一个S3 bucket不仅可以有文件,还可以有带前缀的文件。如果您使用 --recursive,它不仅会列出文件,还会列出前缀。如果您不关心前缀而只关心存储桶中的文件或只关心存储桶中的前缀,这应该可行。

aws s3 ls s3://$S3_BUCKET/$S3_OPTIONAL_PREFIX/ --recursive | awk '{ if( >0) print }'

awk</code> 是文件的大小,如果有前缀则为 <code>0。也可能是文件为空,因此它也会跳过空文件。

编辑:在考虑了 MultiDev 的评论后,之前的解决方案不适用于其中包含空格的对象。我使用 s3api 而不是 s3

aws s3api list-objects --bucket mybucket --prefix myprefix --query 'Contents[].Key' | jq -rc '.[]'

前缀是可选的

使用jq从返回的数组中获取原始元素(键)

使用 --query 'Contents[].{Key: Key, Size: Size}' 之类的东西获取更多信息,然后使用 jq

进一步格式化输出

旧解决方案:aws s3 ls s3://mybucket --recursive | rev | cut -d" " -f1 | rev

我建议不要依赖间距并获取第 4 个字段。

从技术上讲,无论它位于哪个位置,您都需要最后一个字段。

所以使用 rev 更安全...
rev通过char
反转字符串输入char 因此,当您将 aws s3 ls 输出到 rev 时,所有内容都颠倒了,包括字段的位置,因此最后一个字段总是成为第一个字段。
您无需弄清楚最后一个字段的位置,只需 rev,先获取,然后再 rev,因为该字段中的字符也会反过来。

示例:

2013-09-02 21:32:57 23 Bytes foo/bar/.baz/a 变为 a/zab./rab/oof setyB 32 75:23:12 20-90-3102

然后 cut -d" " -f1 将检索第一个字段 a/zab./rab/oof

然后 rev 再次得到 foo/bar/.baz/a

How to display only files from aws s3 ls command?

1. Basic command

$ aws s3 ls s3://bucket --recursive

output :

2021-02-10 15:29:02          0 documents/
2021-02-10 15:29:02         18 documents/data/data.txt
2021-03-15 23:35:12          0 documents/data/my code.txt


2. To get only keys from s3 bucket containing spaces also.

$ aws s3 ls s3://bucket --recursive | awk '{ ===""; print [=10=]}' | cut -c4-

output : 

documents/
documents/data/data.txt
documents/data/my code.txt

3. Removing "documents/" from result

$ aws s3 ls s3://bucket --recursive | awk '[=10=] !~ /\/$/ { ===""; print [=10=]}' | cut -c4-

output :

documents/data/data.txt
documents/data/my code.txt

只是 grep 按起始符号过滤。 “^-”表示行以“-”符号开始。另一方面,目录以字母 'd'

开头
ls -Al | grep "^-"

如果您的文件没有空格,那么这是最简单的方法:

aws s3 ls s3://mybucket  | cut -c32-

输出为:

1.txt.gz
2.txt.gz
3.txt.gz

而不是:

2021-12-15 23:05:44         36 1.txt.gz
2021-12-15 23:05:45         37 2.txt.gz
2021-12-15 23:05:46         39 3.txt.gz