ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

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


B
Benjamin W.

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

尝试这个:

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

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

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

@MichalGasek 如果您像我指定的那样删除 --human-readable 标志,那么它是 4 美元,而不是 5 美元。
不要认为它真的值得另一个答案。例如,在第三个空格之后通过 perl 管道和匹配可以正常工作:aws s3 ls s3://mybucket --recursive | perl -ne '($key)=$_=~/^[\d\-]+\s+[\d\:]+\s+\d+\s(.+?)$/g; print "$key\n";'
替代非 awk 解决方案:aws s3 ls s3://mybucket --recursive | tr -s ' ' | cut -d' ' -f4
我无法验证这是否适用于递归,但由于“简单”版本不适用于文件名中的空格,它似乎是一个脆弱的解决方案,而另一个是不必要的复杂。相反,剪切字符,在 CLI 输出格式更改之前它应该足够健壮:aws s3 ls s3://mybucket | cut -c32-(可选添加递归并验证它仍然有效)
不是所有的英雄穿着斗篷
n
notes-jj

将 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[] = 获取内容对象数组内容

.Key = 获取每个Key Field(不会产生有效的JSON Array,但我们处于原始模式,所以我们不在乎)

附录:

您可以使用纯 AWS CLI,但值将由 \x09 = Horizontal 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 s3api list-buckets | jq -r '.Buckets[].Name'
我喜欢纯 AWS CLI,实际上您可以使用 --query 'Contents[].{Key: Key}' 来实现。然后它将是每行一条记录。
W
Walf

一个简单的过滤器是:

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

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


谢谢。这与空格甚至文件名中的制表符完美配合。节省了很多时间和精力。
s
slm

简单的方法

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

目前,对我来说,aws s3 ls 输出这样您就想在 -c32 上剪切,而不是 -c29;不确定是我的数据还是输出格式的变化。 (我实际上没有子文件夹。)对于 --human-readable 或纯默认输出是这样;列是同一个地方。但实际上,在这种情况下不需要人类可读。无论哪种情况,您都希望省略 --summarize。简而言之,aws s3 ls s3://mybucket | cut -c32-(和 --recursive 仅在需要时)
请注意,如果文件名中有空格,则此处尝试基于空格(awk、cut 等)进行剪切的所有其他答案都将不起作用。
这是最干净的方法(对于带有-c32的michael)
n
nsantana

我的解决方案

使用 aws cli 以递归方式仅列出文件。

aws s3 ls s3://myBucket --recursive | awk 'NF>1{print $4}' | 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 $4}' | grep .

stage.js

当文件名包含“ChatNotes 8Mar.txt”等空格时不起作用。此代码仅打印“ChatNotes”
S
Shoukry

编辑:在考虑了 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


很棒的概念,但是当文件名中有空格时不起作用。
是的...这应该可以工作:aws s3api list-objects --bucket mybucket --prefix myprefix --query 'Contents[].Key' | jq -rc '.[]'
s
skipper21

简单的命令是

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

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


A
AnBisw

S3 存储桶不仅可以包含文件,还可以包含带有前缀的文件。如果您使用 --recursive,它不仅会列出文件,还会列出前缀。如果您不关心前缀,只关心存储桶中的文件,或者只关心存储桶中的前缀,这应该可以工作。

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

awk$3 是文件的大小,如果前缀是 0。也可能是文件为空,因此它也会跳过空文件。


这是不使用 s3api 的解决方案
l
linux_dev
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 '{ $1=$2=$3=""; print $0}' | 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 '$0 !~ /\/$/ { $1=$2=$3=""; print $0}' | cut -c4-

output :

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

M
Michael Silverstein

仅对于文件名,我发现最简单的是:

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

这将在空格 (cut -d " ") 处截断返回的输出并返回第四列 (-f 4),即文件名列表。


这似乎并不像我的 awk 解决方案那样始终如一。
打破 --human-readable... 编辑:实际上也没有。
M
Mostafa Wael

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

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

S
Savvasenok

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

ls -Al | grep "^-"