

**本文档仅适用于 AWS CLI 版本 1。**

我们已宣布即将终止对 AWS CLI 版本 1 的支持。建议您迁移到 AWS CLI 版本 2。有关日期、其它详细信息以及如何迁移的信息，请参阅[公告](https://aws.amazon.com/blogs/developer/cli-v1-maintenance-mode-announcement/)。有关 AWS CLI 版本 2 的相关文档，请参阅[版本 2 用户指南](https://docs.aws.amazon.com/cli/latest/userguide/)。

# 在 AWS CLI 中控制命令输出
<a name="cli-usage-output"></a>

本部分介绍控制 AWS Command Line Interface (AWS CLI) 的输出的不同方式。在终端中自定义 AWS CLI 输出可以提高可读性，简化脚本自动化，并为浏览大型数据集提供便利。

AWS CLI 支持多种[输出格式](cli-usage-output-format.md)，包括 [`json`](cli-usage-output-format.md#json-output)、[`text`](cli-usage-output-format.md#text-output)、 和 [`table`](cli-usage-output-format.md#table-output)。有些服务在服务器端对数据进行了[分页](cli-usage-pagination.md)，

最后，AWS CLI 具有[服务器端和客户端筛选功能](cli-usage-filter.md)，您可以单独使用一个功能或同时使用这两个功能来筛选 AWS CLI 输出。

**Topics**
+ [敏感输出](#cli-usage-output-sensitive)
+ [服务器端与客户端输出选项](#cli-usage-output-server-client)
+ [在 AWS CLI 中设置输出格式](cli-usage-output-format.md)
+ [AWS CLI 中的结构化错误输出](cli-usage-error-format.md)
+ [在 AWS CLI 中使用分页选项](cli-usage-pagination.md)
+ [在 AWS CLI 中筛选输出](cli-usage-filter.md)

## 敏感输出
<a name="cli-usage-output-sensitive"></a>

AWS CLI 中的某些操作可能会返回可能被视为敏感内容的信息，包括来自环境变量的信息。在某些情况下，泄露这些信息可能构成安全风险；例如，这些信息可能包含在持续集成和持续部署（CI/CD）日志中。因此，请务必核查何时将此类输出作为日志的一部分，并在不需要时隐藏该输出。

有关保护敏感数据的其他信息，请参阅[AWS CLI 中的数据保护](data-protection.md)。

考虑下面的最佳实践：
+ 请考虑以编程方式从密钥存储库（如 AWS Secrets Manager）中检索您的密钥。
+ 查看构建日志的内容，确保其中不包含敏感信息。考虑使用诸如 `/dev/null` 管道传输或将输出捕获为 bash 或 PowerShell 变量之类的方法，来抑制命令输出。

  以下是将输出（而不是错误）重定向到 `/dev/null` 的 bash 示例：

  ```
  $ aws s3 ls > /dev/null
  ```

  有关抑制终端输出的详细信息，请参阅所用终端的用户文档。
+ 考虑日志的访问权限，并根据您的使用案例适当确定访问范围。

## 服务器端与客户端输出选项
<a name="cli-usage-output-server-client"></a>

AWS CLI 具有[服务器端和客户端筛选功能](cli-usage-filter.md)，您可以单独使用或结合使用这两项功能来筛选 AWS CLI 输出。首先处理服务器端筛选，然后返回输出以进行客户端筛选。服务器端筛选由服务 API 提供支持。客户端筛选使用 `--query` 参数由 AWS CLI 客户端提供支持。

**服务器端**输出选项是 AWS 服务 API 直接支持的功能。任何经过筛选或分页的数据都不会发送到客户端，这可以缩短 HTTP 响应时间，并为较大的数据集提高带宽。

**客户端**输出选项是由 AWS CLI 创建的功能。所有数据都发送到客户端，然后 AWS CLI 会对显示的内容进行筛选或分页。对于较大的数据集，客户端操作不会加快速度或节省带宽。

当服务器端和客户端选项同时使用时，服务器端操作会首先完成，然后发送到客户端进行客户端操作。这利用了服务器端选项可以加快速度和节省带宽的特点，同时使用其他 AWS CLI 功能来获得所需的输出。

# 在 AWS CLI 中设置输出格式
<a name="cli-usage-output-format"></a>

本主题介绍了 AWS Command Line Interface (AWS CLI) 的不同输出格式。AWS CLI 支持以下输出格式：
+ **[`json`](#json-output)** – 输出采用 [JSON](https://json.org/) 字符串的格式。
+ **[`text`](#text-output)** – 输出采用多个制表符分隔字符串值行的格式。这对于将输出传递到文本处理器（如 `grep`、`sed` 或 `awk`）很有用。
+ **[`table`](#table-output)** – 输出采用表格形式，使用字符 \$1\$1- 以形成单元格边框。它通常以“人性化”格式呈现信息，这种格式比其他格式更容易阅读，但从编程方面来讲不是那么有用。

## 如何选择输出格式
<a name="cli-usage-output-format-how"></a>

正如[配置](cli-chap-configure.md)主题所述，输出格式可通过三种不同方式指定：
+ **在 `config` 文件的命名配置文件中使用 `output` 选项** – 以下示例将默认输出格式设置为 `text`。

  ```
  [default]
  output=text
  ```
+ **使用 `AWS_DEFAULT_OUTPUT` 环境变量** – 对于此命令行会话中的命令，以下输出将格式设置为 `table`，直到更改此变量或会话结束。使用此环境变量将覆盖在 `config` 文件中设置的任何值。

  ```
  $ export AWS_DEFAULT_OUTPUT="table"
  ```
+ **在命令行上使用 `--output` 选项** – 以下示例仅将这一个命令的输出设置为 `json`。对此命令使用此选项将覆盖任何当前设置的环境变量或 `config` 文件中的值。

  ```
  $ aws swf list-domains --registration-status REGISTERED --output json
  ```

**重要**  
指定的输出类型更改`--query` 选项的运行方式：  
如果您指定 `--output text`，则在应用 `--query` 筛选条件*之前*，输出采用分页方式，并且 AWS CLI 会在输出的*每个页面*上运行查询一次。因此，查询在每个页面上包括第一个匹配元素，这可能会导致意外的额外输出。要进一步筛选输出，您可以使用其他命令行工具，例如 `head` 或 `tail`。
如果您指定 `--output json`、，则在应用 `--query` 筛选条件之前，输出会完全处理为单个本机结构。AWS CLI 仅针对整个结构运行查询一次，同时生成筛选的结果，然后将结果输出。

## JSON 输出格式
<a name="json-output"></a>

[JSON](https://json.org) 是 AWS CLI 的默认输出格式。大多数编程语言可以使用内置函数或公开提供的库轻松解码 JSON 字符串。您可以通过强有力的方式将 JSON 输出与 [--query 选项](cli-usage-filter.md)结合使用，以筛选和格式化 AWS CLI JSON 格式的输出。

对于您可能无法使用 `--query` 执行的更高级的筛选，可以考虑使用 `jq`，这是一个命令行 JSON 处理器。您可以在以下网址下载它并找到正式的教程：[http://stedolan.github.io/jq/](http://stedolan.github.io/jq/)。

以下是 JSON 输出的示例。

```
$ aws iam list-users --output json
```

```
{
    "Users": [
        {
            "Path": "/",
            "UserName": "Admin",
            "UserId": "AIDA1111111111EXAMPLE",
            "Arn": "arn:aws:iam::123456789012:user/Admin",
            "CreateDate": "2014-10-16T16:03:09+00:00",
            "PasswordLastUsed": "2016-06-03T18:37:29+00:00"
        },
        {
            "Path": "/backup/",
            "UserName": "backup-user",
            "UserId": "AIDA2222222222EXAMPLE",
            "Arn": "arn:aws:iam::123456789012:user/backup/backup-user",
            "CreateDate": "2019-09-17T19:30:40+00:00"
        },
        {
            "Path": "/",
            "UserName": "cli-user",
            "UserId": "AIDA3333333333EXAMPLE",
            "Arn": "arn:aws:iam::123456789012:user/cli-user",
            "CreateDate": "2019-09-17T19:11:39+00:00"
        }
    ]
}
```

## 文本输出格式
<a name="text-output"></a>

`text` 格式将 AWS CLI 输出组织为制表符分隔的行。此格式适合在传统 Unix 文本工具（如 `grep`、`sed` 和 `awk`）和由 PowerShell 执行的文本处理中使用。

`text` 输出格式遵循以下所示的基本结构。这些列根据底层 JSON 对象相应的键名称按字母顺序排序。

```
IDENTIFIER  sorted-column1 sorted-column2
IDENTIFIER2 sorted-column1 sorted-column2
```

下面是 `text` 输出的一个示例。每个字段都用标签与其他字段分开，并带有一个额外的标签，其中有一个空字段。

```
$ aws iam list-users --output text
```

```
USERS   arn:aws:iam::123456789012:user/Admin                2014-10-16T16:03:09+00:00   2016-06-03T18:37:29+00:00   /          AIDA1111111111EXAMPLE   Admin
USERS   arn:aws:iam::123456789012:user/backup/backup-user   2019-09-17T19:30:40+00:00                               /backup/   AIDA2222222222EXAMPLE   backup-user
USERS   arn:aws:iam::123456789012:user/cli-user             2019-09-17T19:11:39+00:00                               /          AIDA3333333333EXAMPLE   cli-user
```

第四列是 `PasswordLastUsed` 字段，它对于最后两个条目为空，因为这些用户从未登录过 AWS 管理控制台。

**重要**  
*我们强烈建议，如果您指定 `text` 输出，则也始终使用 [`--query`](cli-usage-filter.md) 选项以确保行为一致*。  
这是因为文本格式按由 AWS 服务返回的基础 JSON 对象的键名称以字母顺序对输出列进行排序，而类似的资源可能没有相同的键名称。例如，基于 Linux 的 Amazon EC2 实例的 JSON 表示形式中的元素在基于 Windows 的实例的 JSON 表示形式中可能不存在，反之亦然。此外，资源可能在未来的更新中添加或移除键/值元素，从而修改列的顺序。因此，可以使用 `--query` 补充 `text` 输出的功能，以提供对输出格式的完全控制。  
在以下示例中，命令指定要显示的元素，并使用列表表示法 `[key1, key2, ...]` 来*定义列的顺序*。这可让您十分放心：正确的键值始终显示在预期的列中。最后请注意，对于不存在的键，AWS CLI 将输出 `None` 作为键值。  

```
$ aws iam list-users --output text --query 'Users[*].[UserName,Arn,CreateDate,PasswordLastUsed,UserId]'
```

```
Admin         arn:aws:iam::123456789012:user/Admin         2014-10-16T16:03:09+00:00   2016-06-03T18:37:29+00:00   AIDA1111111111EXAMPLE
backup-user   arn:aws:iam::123456789012:user/backup-user   2019-09-17T19:30:40+00:00   None                        AIDA2222222222EXAMPLE
cli-user      arn:aws:iam::123456789012:user/cli-backup    2019-09-17T19:11:39+00:00   None                        AIDA3333333333EXAMPLE
```

以下示例显示如何将 `grep` 和 `awk` 与来自 `text` 命令的 `aws ec2 describe-instances` 输出结合使用。第一个命令在 `text` 输出中显示每个实例的可用区、当前状态和实例 ID。第二个命令处理该输出，以仅输出在 `us-west-2a` 可用区中运行的所有实例的实例 ID。

```
$ aws ec2 describe-instances --query 'Reservations[*].Instances[*].[Placement.AvailabilityZone, State.Name, InstanceId]' --output text
```

```
us-west-2a      running i-4b41a37c
us-west-2a      stopped i-a071c394
us-west-2b      stopped i-97a217a0
us-west-2a      running i-3045b007
us-west-2a      running i-6fc67758
```

```
$ aws ec2 describe-instances --query 'Reservations[*].Instances[*].[Placement.AvailabilityZone, State.Name, InstanceId]' --output text | grep us-west-2a | grep running | awk '{print $3}'
```

```
i-4b41a37c
i-3045b007
i-6fc67758
```

以下示例更进一步，不仅说明如何筛选输出，还介绍如何使用该输出自动更改每个已停止实例的实例类型。

```
$ aws ec2 describe-instances --query 'Reservations[*].Instances[*].[State.Name, InstanceId]' --output text |
> grep stopped |
> awk '{print $2}' |
> while read line;
> do aws ec2 modify-instance-attribute --instance-id $line --instance-type '{"Value": "m1.medium"}';
> done
```

`text` 输出也适用于 PowerShell。因为 `text` 输出中的列使用制表符分隔，所以可以轻松地使用 PowerShell 的 ``t` 分隔符将输出拆分为数组。以下命令在第一列 (`InstanceId`) 与字符串 `AvailabilityZone` 匹配的情况下显示第三列 (`us-west-2a`) 的值。

```
PS C:\>aws ec2 describe-instances --query 'Reservations[*].Instances[*].[Placement.AvailabilityZone, State.Name, InstanceId]' --output text |
%{if ($_.split("`t")[0] -match "us-west-2a") { $_.split("`t")[2]; } }
```

```
-4b41a37c
i-a071c394
i-3045b007
i-6fc67758
```

注意，尽管上一个示例的确显示了如何使用 `--query` 参数解析底层 JSON 对象和提取所需的列，但是 PowerShell 有自己处理 JSON 的功能（如果跨平台兼容性不是问题）。不像大多数命令 shell 需要的那样将输出处理为文本，PowerShell 让您可以使用 `ConvertFrom-JSON` cmdlet 生成具有层次结构的对象。然后，您可以直接从该对象访问所需的成员。

```
(aws ec2 describe-instances --output json | ConvertFrom-Json).Reservations.Instances.InstanceId
```

**提示**  
如果使用 `--query` 参数输出文本并将输出筛选到单个字段，则输出是单行制表符分隔值。要将每个值放到单独的行上，可以将输出字段放在括号中，如以下示例所示。  
制表符分隔的单行输出：  

```
$ aws iam list-groups-for-user --user-name susan  --output text --query "Groups[].GroupName"
```

```
HRDepartment    Developers      SpreadsheetUsers  LocalAdmins
```
通过将 `[GroupName]` 放在括号中，让每个值都在自己的行上：  

```
$ aws iam list-groups-for-user --user-name susan  --output text --query "Groups[].[GroupName]"
```

```
HRDepartment
Developers
SpreadsheetUsers
LocalAdmins
```

## 表输出格式
<a name="table-output"></a>

`table` 格式以表格形式生成复杂 AWS CLI 输出的易于人阅读的表示。

```
$ aws iam list-users --output table
```

```
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
|                                                                                 ListUsers                                                                     |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
||                                                                                  Users                                                                      ||
|+----------------------------------------------------+---------------------------+---------------------------+----------+-----------------------+-------------+|
||                         Arn                        |       CreateDate          |    PasswordLastUsed       |   Path   |        UserId         |   UserName  ||
|+----------------------------------------------------+---------------------------+---------------------------+----------+-----------------------+-------------+|
||  arn:aws:iam::123456789012:user/Admin              | 2014-10-16T16:03:09+00:00 | 2016-06-03T18:37:29+00:00 | /        | AIDA1111111111EXAMPLE | Admin       ||
||  arn:aws:iam::123456789012:user/backup/backup-user | 2019-09-17T19:30:40+00:00 |                           | /backup/ | AIDA2222222222EXAMPLE | backup-user ||
||  arn:aws:iam::123456789012:user/cli-user           | 2019-09-17T19:11:39+00:00 |                           | /        | AIDA3333333333EXAMPLE | cli-user    ||
+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
```

您可以将 `--query` 选项与 `table` 格式结合使用，以显示从原始输出中预先选择的一系列元素。请注意字典和列表表示法之间的输出区别：在第一个示例中，列名按字母顺序排序；在第二个示例中，未命名的列按用户指定的顺序排序。有关 `--query` 选项的更多信息，请参阅 [在 AWS CLI 中筛选输出](cli-usage-filter.md)。

```
$ aws ec2 describe-volumes --query 'Volumes[*].{ID:VolumeId,InstanceId:Attachments[0].InstanceId,AZ:AvailabilityZone,Size:Size}' --output table
```

```
------------------------------------------------------
|                   DescribeVolumes                  | 
+------------+----------------+--------------+-------+
|     AZ     |      ID        | InstanceId   | Size  |
+------------+----------------+--------------+-------+
|  us-west-2a|  vol-e11a5288  |  i-a071c394  |  30   |
|  us-west-2a|  vol-2e410a47  |  i-4b41a37c  |  8    |
+------------+----------------+--------------+-------+
```

```
$ aws ec2 describe-volumes --query 'Volumes[*].[VolumeId,Attachments[0].InstanceId,AvailabilityZone,Size]' --output table
```

```
----------------------------------------------------
|                  DescribeVolumes                 |
+--------------+--------------+--------------+-----+
|  vol-e11a5288|  i-a071c394  |  us-west-2a  |  30 |
|  vol-2e410a47|  i-4b41a37c  |  us-west-2a  |  8  |
+--------------+--------------+--------------+-----+
```

# AWS CLI 中的结构化错误输出
<a name="cli-usage-error-format"></a>

本主题介绍 AWS Command Line Interface（AWS CLI）的结构化错误输出格式。CLI 将错误写入到 stderr 并支持以下格式：
+ **[`enhanced`](#cli-error-format-enhanced)**（默认）：内联显示带有其它详细信息的错误消息。用于便于阅读的调试。
+ **[`json`](#cli-error-format-json)**：输出采用 [JSON](https://json.org/) 字符串的格式并具有所有错误字段。用于自动化和脚本编写。
+ **[`yaml`](#cli-error-format-yaml)**：输出采用 [YAML](https://yaml.org/) 字符串的格式并具有所有错误字段。用于自动化和脚本编写。
+ **[`text`](#cli-error-format-text)**：使用文本格式化程序格式化错误。用于快速可视化扫描。
+ **[`table`](#cli-error-format-table)**：使用表格式化程序格式化错误。用于快速可视化扫描。
+ **[`legacy`](#cli-error-format-legacy)**：没有结构化详细信息的原始错误格式。用于保持向后兼容性。

## 配置错误格式
<a name="cli-error-format-configuring"></a>

您可以使用以下任何方法配置错误格式：

命令行标志  

```
$ aws <command> --cli-error-format json
```

配置文件（`~/.aws/config`）  

```
[default]
cli_error_format = json
```

环境变量  

```
$ export AWS_CLI_ERROR_FORMAT=yaml
```

## 错误输出格式
<a name="cli-error-output-formats"></a>

以下各节介绍每种格式：

### 增强格式（默认）
<a name="cli-error-format-enhanced"></a>

增强格式显示错误消息，并包含简单值的其它内联详细信息。对于复杂的结构，该格式会提供使用 JSON 或 YAML 的提示。

**示例：缺少区域配置**

```
aws: [ERROR]: An error occurred (NoRegion): You must specify a region. You can also configure your region by running "aws configure".
```

**示例：带有其它字段的 S3 存储桶不存在**

```
aws: [ERROR]: An error occurred (NoSuchBucket) when calling the GetObject operation: The specified bucket does not exist

Additional error details:
BucketName: amzn-s3-demo-bucket
```

**示例：复杂的错误字段**

```
An error occurred (TransactionCanceledException) when calling the TransactWriteItems operation: Transaction cancelled, please refer cancellation reasons for specific reasons [ConditionalCheckFailed, None]

Additional error details:
CancellationReasons: <complex value>
Use "--cli-error-format json" or another error format to see the full details.
```

### JSON 格式
<a name="cli-error-format-json"></a>

JSON 格式提供包含所有错误字段的结构化表示形式。

**示例：缺少区域配置**

```
{
    "Code": "NoRegion",
    "Message": "You must specify a region. You can also configure your region by running \"aws configure\"."
}
```

**示例：S3 存储桶不存在**

```
{
    "Code": "NoSuchBucket",
    "Message": "The specified bucket does not exist",
    "BucketName": "amzn-s3-demo-bucket"
}
```

### YAML 格式
<a name="cli-error-format-yaml"></a>

YAML 格式提供包含所有错误字段的结构化表示形式。

**示例：缺少区域配置**

```
Code: NoRegion
Message: You must specify a region. You can also configure your region by running "aws configure".
```

**示例：S3 存储桶不存在**

```
Code: NoSuchBucket
Message: The specified bucket does not exist
BucketName: amzn-s3-demo-bucket
```

### 文本格式
<a name="cli-error-format-text"></a>

文本格式使用与成功命令输出相同的格式化程序。

**示例：S3 存储桶不存在**

```
amzn-s3-demo-bucket  NoSuchBucket    The specified bucket does not exist
```

### 表格式
<a name="cli-error-format-table"></a>

表格式使用与成功命令输出相同的格式化程序。

**示例：S3 存储桶不存在**

```
-------------------------------------------------------------------------------------|
|                                       error                                        |
+---------------------------+---------------+----------------------------------------+
|        BucketName         |     Code      |                Message                 |
+---------------------------+---------------+----------------------------------------+
|  amzn-s3-demo-bucket      |  NoSuchBucket |  The specified bucket does not exist   |
+---------------------------+---------------+----------------------------------------+
```

### 旧版格式
<a name="cli-error-format-legacy"></a>

旧版格式提供原始错误格式，而不包含结构化详细信息。此格式不包括 CLI 异常的“An error occurred (ErrorCode)”前缀。

**示例：缺少区域配置**

```
aws: [ERROR]: You must specify a region. You can also configure your region by running "aws configure".
```

**示例：S3 存储桶不存在**

```
An error occurred (NoSuchBucket) when calling the GetObject operation: The specified bucket does not exist
```

**注意**  
现在，错误始终包含 CLI 异常的 `aws: [ERROR]:` 前缀。早期版本并不总是包含此前缀。  
无论所配置的错误格式如何，以下异常都始终使用旧版格式：  
`UnknownArgumentError`：显示使用信息。
键盘中断 (`KeyboardInterrupt`)

## 完整示例
<a name="cli-error-format-example"></a>

以下示例显示采用 JSON 错误格式的命令：

```
$ aws s3api get-object \
    --bucket amzn-s3-demo-bucket \
    --key file.txt out.txt \
    --cli-error-format json
```

输出 (stderr)：

```
{
    "Code": "NoSuchBucket",
    "Message": "The specified bucket does not exist",
    "BucketName": "amzn-s3-demo-bucket"
}
```

`BucketName` 字段是 Amazon S3 服务返回的建模错误成员。

# 在 AWS CLI 中使用分页选项
<a name="cli-usage-pagination"></a>

本主题介绍分页 AWS Command Line Interface（AWS CLI）的输出的不同方式。

## 服务器端分页
<a name="cli-usage-pagination-serverside"></a>

对于返回大型项目列表的大多数命令，AWS CLI 提供了多个服务器端选项，当 AWS CLI 调用服务 API 以填充此列表时，您可以使用这些选项控制输出中包括的项目数。AWS CLI 中的服务器端分页由 AWS 服务 API 启用，因此，这些选项只有在服务 API 启用它们时才生效。

**Topics**
+ [--no-paginate](#cli-usage-pagination-nopaginate)
+ [--page-size](#cli-usage-pagination-pagesize)
+ [--max-items](#cli-usage-pagination-maxitems)
+ [--starting-token](#cli-usage-pagination-startingtoken)

默认情况下，AWS CLI 使用由单个服务确定的页面大小并检索所有可用项目。例如，Amazon S3 的原定设置页面大小为 1000。如果您在包含 3500 个对象的 Amazon S3 存储桶上运行 `aws s3api list-objects`，则 AWS CLI 将自动对 Amazon S3 发出四次调用，以在后台处理服务特定分页逻辑并在最终输出中返回所有 3500 个对象。

有关特定命令是否具有服务器端分页的信息，请参阅[《AWS CLI 参考指南》](https://docs.aws.amazon.com/cli/v1/reference/)。

### 如何使用 --no-paginate 参数
<a name="cli-usage-pagination-nopaginate"></a>

`--no-paginate` 选项在客户端禁用以下分页标记。使用命令时，默认情况下 AWS CLI 会自动执行多次调用，返回所有可能的结果来创建分页。每页显示一次调用的结果。禁用分页时，AWS CLI 只执行一次调用，显示命令结果的第一页。

例如，如果您在包含 3500 个对象的 Amazon S3 存储桶上运行 `aws s3api list-objects`，则 AWS CLI 只会执行对 Amazon S3 的第一个调用，并在最终输出中仅返回前 1000 个对象。

```
$ aws s3api list-objects \
    --bucket amzn-s3-demo-bucket \
    --no-paginate
{
    "Contents": [
...
```

### 如何使用 --page-size 参数
<a name="cli-usage-pagination-pagesize"></a>

如果您在对大量资源运行列表命令时发现问题，则表明原定设置页面大小可能过大。这可能会导致对 AWS 服务的调用超过允许的最大时间并生成“超时”错误。您可以使用 `--page-size` 选项来指定 AWS CLI 从对 AWS 服务的每个调用请求数量较少的项目。AWS CLI 仍将检索完整列表，但会在后台执行大量服务 API 调用，并减少每次调用时检索的项目数。这样，各个调用成功的可能性会更高且不会发生超时。更改页面大小不会影响输出；它只影响生成输出所需进行的 API 调用数。

```
$ aws s3api list-objects \
    --bucket amzn-s3-demo-bucket \
    --page-size 100
{
    "Contents": [
...
```

### 如何使用 --max-items 参数
<a name="cli-usage-pagination-maxitems"></a>

要在 AWS CLI 输出中一次包括更少的项目，请使用 `--max-items` 选项。AWS CLI 仍会按之前所述使用该服务处理分页，但只打印您指定的一次检索的项目数。

```
$ aws s3api list-objects \
    --bucket amzn-s3-demo-bucket \
    --max-items 100
{
    "NextToken": "eyJNYXJrZXIiOiBudWxsLCAiYm90b190cnVuY2F0ZV9hbW91bnQiOiAxfQ==",
    "Contents": [
...
```

### 如何使用 --starting-token 参数
<a name="cli-usage-pagination-startingtoken"></a>

如果项目输出的数量（`--max-items`）少于基础 API 调用所返回的项目总数，则输出将包含您可传递到后续命令的 `NextToken` 以检索下一组项目。以下示例显示如何使用上一示例返回的 `NextToken` 值，并使您能够检索接下来的 100 个项目。

**注意**  
参数 `--starting-token` 不能为空。如果上一个命令未返回 `NextToken` 值，则没有更多项目可返回，您不需要再次调用该命令。

```
$ aws s3api list-objects \
    --bucket amzn-s3-demo-bucket \
    --max-items 100 \
    --starting-token eyJNYXJrZXIiOiBudWxsLCAiYm90b190cnVuY2F0ZV9hbW91bnQiOiAxfQ==
{
    "Contents": [
...
```

每次调用指定的 AWS 服务时返回项目的顺序可能不同。如果您为 `--page-size` 和 `--max-items` 指定不同的值，您可能会获得意外结果（项目缺失或重复）。为防止出现这种情况，请对 `--page-size` 和 `--max-items` 使用相同的数字，以同步 AWS CLI 的分页与基础服务的分页。您还可以检索整个列表并在本地执行任何必需的分页操作。

# 在 AWS CLI 中筛选输出
<a name="cli-usage-filter"></a>

AWS Command Line Interface（AWS CLI）具有服务器端和客户端筛选功能，您可以单独使用或结合使用这两项功能来筛选 AWS CLI 输出。首先处理服务器端筛选，然后返回输出以进行客户端筛选。
+ 服务器端筛选由 API 提供支持，通常使用 `--filter` 参数来实现筛选。该服务仅返回匹配结果，这可以加快大型数据集的 HTTP 响应时间。
+ 客户端筛选使用 `--query` 参数由 AWS CLI 客户端提供支持。此参数具有服务器端筛选可能没有的功能。

**Topics**
+ [服务器端筛选](#cli-usage-filter-server-side)
+ [客户端筛选](#cli-usage-filter-client-side)
+ [结合服务器端和客户端筛选](#cli-usage-filter-combining)
+ [其他资源](#cli-usage-filter-resources)

## 服务器端筛选
<a name="cli-usage-filter-server-side"></a>

AWS CLI 中的服务器端筛选由 AWS 服务 API 提供。该 AWS 服务仅返回 HTTP 响应中与筛选条件匹配的记录，这可以加快大型数据集的 HTTP 响应时间。由于服务器端筛选由服务 API 定义，因此参数名称和函数因服务而异。用于筛选的一些常见参数名称包括：
+ `--filter`，例如 [ses](https://docs.aws.amazon.com/cli/v1/reference/ses/create-receipt-filter.html) 和 [ce](https://docs.aws.amazon.com/cli/v1/reference/ce/get-cost-and-usage.html)。
+ `--filters`，例如 [ec2](https://docs.aws.amazon.com/cli/v1/reference/ec2/describe-volumes.html)、[autoscaling](https://docs.aws.amazon.com/cli/v1/reference/autoscaling/describe-tags.html) 和 [rds](https://docs.aws.amazon.com/cli/v1/reference/rds/describe-db-instances.html)。
+ 以单词 `filter` 开头的名称，例如 `--filter-expression` 用于 [https://docs.aws.amazon.com/cli/v1/reference/dynamodb/scan.html](https://docs.aws.amazon.com/cli/v1/reference/dynamodb/scan.html) 命令。

有关特定命令是否具有服务器端筛选和筛选规则的信息，请参阅 [AWS CLI 参考指南](https://docs.aws.amazon.com/cli/v1/reference/)。

## 客户端筛选
<a name="cli-usage-filter-client-side"></a>

AWS CLI 使用 `--query` 参数提供内置的基于 JSON 的客户端筛选功能。该 `--query` 参数是一个功能强大的工具，可用来自定义输出的内容和样式。该 `--query` 参数可获取从服务器返回的 HTTP 响应，并在显示结果之前对结果进行筛选。由于在筛选之前将整个 HTTP 响应发送到客户端，因此客户端筛选速度可能比大型数据集的服务器端筛选更慢。

查询使用 [JMESPath 语法](https://jmespath.org/)来创建用于筛选输出的表达式。要了解 JMESPath 语法，请参阅 *JMESPath 网站*上的[教程](https://jmespath.org/tutorial.html)。

**重要**  
指定的输出类型更改`--query` 选项的运行方式：  
如果您指定 `--output text`，则在应用 `--query` 筛选条件*之前*，输出采用分页方式，并且 AWS CLI 会在输出的*每个页面*上运行查询一次。因此，查询在每个页面上包括第一个匹配元素，这可能会导致意外的额外输出。要进一步筛选输出，您可以使用其他命令行工具，例如 `head` 或 `tail`。
如果您指定 `--output json`、，则在应用 `--query` 筛选条件之前，输出会完全处理为单个本机结构。AWS CLI 仅针对整个结构运行查询一次，同时生成筛选的结果，然后将结果输出。

**Topics**
+ [开始之前](#cli-usage-filter-client-side-output)
+ [标识符](#cli-usage-filter-client-side-identifiers)
+ [从列表中选择](#cli-usage-filter-client-side-select-list)
+ [筛选嵌套数据](#cli-usage-filter-client-side-nested)
+ [展平结果](#cli-usage-filter-client-side-specific-flattening)
+ [筛选特定值](#cli-usage-filter-client-side-specific-values)
+ [传输表达式](#cli-usage-filter-client-side-pipe)
+ [筛选多个标识符值](#cli-usage-filter-client-side-miltiselect-list)
+ [将标签添加到标识符值](#cli-usage-filter-client-side-multiselect-hash)
+ [函数](#cli-usage-filter-client-side-functions)
+ [高级 `--query` 示例](#cli-usage-filter-client-side-advanced)

### 开始之前
<a name="cli-usage-filter-client-side-output"></a>

**注意**  
这些筛选表达式示例是为基本 Linux 式 Shell 编写的。在使用这些示例时，请务必为终端 Shell 使用正确的引用规则。终端解释输入的方式可能会极大地改变发送到 AWS CLI 的内容。终端读取单引号 `'`、双引号 `"` 或反引号 ``` 的方式会更改内容的读取方式。  
有关更多信息，请参阅 [在 AWS CLI 中将引号和文本与字符串结合使用](cli-usage-parameters-quoting-strings.md)。

以下 JSON 输出显示了 `--query` 参数可以生成的示例。此输出描述了附加到单独 Amazon EC2 实例的三个 Amazon EBS 卷。

#### 示例输出
<a name="cli-usage-filter-client-side-output-example"></a>

```
$ aws ec2 describe-volumes
{
  "Volumes": [
    {
      "AvailabilityZone": "us-west-2a",
      "Attachments": [
        {
          "AttachTime": "2013-09-17T00:55:03.000Z",
          "InstanceId": "i-a071c394",
          "VolumeId": "vol-e11a5288",
          "State": "attached",
          "DeleteOnTermination": true,
          "Device": "/dev/sda1"
        }
      ],
      "VolumeType": "standard",
      "VolumeId": "vol-e11a5288",
      "State": "in-use",
      "SnapshotId": "snap-f23ec1c8",
      "CreateTime": "2013-09-17T00:55:03.000Z",
      "Size": 30
    },
    {
      "AvailabilityZone": "us-west-2a",
      "Attachments": [
        {
          "AttachTime": "2013-09-18T20:26:16.000Z",
          "InstanceId": "i-4b41a37c",
          "VolumeId": "vol-2e410a47",
          "State": "attached",
          "DeleteOnTermination": true,
          "Device": "/dev/sda1"
        }
      ],
      "VolumeType": "standard",
      "VolumeId": "vol-2e410a47",
      "State": "in-use",
      "SnapshotId": "snap-708e8348",
      "CreateTime": "2013-09-18T20:26:15.000Z",
      "Size": 8
    },
    {
      "AvailabilityZone": "us-west-2a",
      "Attachments": [
        {
          "AttachTime": "2020-11-20T19:54:06.000Z",
          "InstanceId": "i-1jd73kv8",
          "VolumeId": "vol-a1b3c7nd",
          "State": "attached",
          "DeleteOnTermination": true,
          "Device": "/dev/sda1"
        }
      ],
      "VolumeType": "standard",
      "VolumeId": "vol-a1b3c7nd",
      "State": "in-use",
      "SnapshotId": "snap-234087fb",
      "CreateTime": "2020-11-20T19:54:05.000Z",
      "Size": 15
    }
  ]
}
```

### 标识符
<a name="cli-usage-filter-client-side-identifiers"></a>

标识符是输出值的标签。创建筛选条件时，您可以使用标识符缩小查询结果的范围。在以下输出示例中，所有标识符（如 `Volumes`、`AvailabilityZone` 和 `AttachTime`）都将突出显示。

```
$ aws ec2 describe-volumes
{
  "Volumes": [
    {
      "AvailabilityZone": "us-west-2a",
      "Attachments": [
        {
          "AttachTime": "2013-09-17T00:55:03.000Z",
          "InstanceId": "i-a071c394",
          "VolumeId": "vol-e11a5288",
          "State": "attached",
          "DeleteOnTermination": true,
          "Device": "/dev/sda1"
        }
      ],
      "VolumeType": "standard",
      "VolumeId": "vol-e11a5288",
      "State": "in-use",
      "SnapshotId": "snap-f23ec1c8",
      "CreateTime": "2013-09-17T00:55:03.000Z",
      "Size": 30
    },
    {
      "AvailabilityZone": "us-west-2a",
      "Attachments": [
        {
          "AttachTime": "2013-09-18T20:26:16.000Z",
          "InstanceId": "i-4b41a37c",
          "VolumeId": "vol-2e410a47",
          "State": "attached",
          "DeleteOnTermination": true,
          "Device": "/dev/sda1"
        }
      ],
      "VolumeType": "standard",
      "VolumeId": "vol-2e410a47",
      "State": "in-use",
      "SnapshotId": "snap-708e8348",
      "CreateTime": "2013-09-18T20:26:15.000Z",
      "Size": 8
    },
    {
      "AvailabilityZone": "us-west-2a",
      "Attachments": [
        {
          "AttachTime": "2020-11-20T19:54:06.000Z",
          "InstanceId": "i-1jd73kv8",
          "VolumeId": "vol-a1b3c7nd",
          "State": "attached",
          "DeleteOnTermination": true,
          "Device": "/dev/sda1"
        }
      ],
      "VolumeType": "standard",
      "VolumeId": "vol-a1b3c7nd",
      "State": "in-use",
      "SnapshotId": "snap-234087fb",
      "CreateTime": "2020-11-20T19:54:05.000Z",
      "Size": 15
    }
  ]
}
```

有关更多信息，请参阅 *JMESPath 网站*上的[标识符](https://jmespath.org/specification.html#identifiers )。

### 从列表中选择
<a name="cli-usage-filter-client-side-select-list"></a>

列表或数组是后跟方括号“`[`”的标识符，例如 `Volumes` 中的 `Attachments` 和 [开始之前](#cli-usage-filter-client-side-output)。

**语法**

```
<listName>[ ]
```

要筛选数组的所有输出，可以使用通配符表示法。[通配符](http://jmespath.org/specification.html#wildcard-expressions)表达式是用于使用 `*` 表示法返回元素的表达式。

以下示例查询所有 `Volumes` 内容。

```
$ aws ec2 describe-volumes \
    --query 'Volumes[*]'
[
  {
    "AvailabilityZone": "us-west-2a",
    "Attachments": [
      {
        "AttachTime": "2013-09-17T00:55:03.000Z",
        "InstanceId": "i-a071c394",
        "VolumeId": "vol-e11a5288",
        "State": "attached",
        "DeleteOnTermination": true,
        "Device": "/dev/sda1"
      }
    ],
    "VolumeType": "standard",
    "VolumeId": "vol-e11a5288",
    "State": "in-use",
    "SnapshotId": "snap-f23ec1c8",
    "CreateTime": "2013-09-17T00:55:03.000Z",
    "Size": 30
  },
  {
    "AvailabilityZone": "us-west-2a",
    "Attachments": [
      {
        "AttachTime": "2020-11-20T19:54:06.000Z",
        "InstanceId": "i-1jd73kv8",
        "VolumeId": "vol-a1b3c7nd",
        "State": "attached",
        "DeleteOnTermination": true,
        "Device": "/dev/sda1"
      }
    ],
    "VolumeType": "standard",
    "VolumeId": "vol-a1b3c7nd",
    "State": "in-use",
    "SnapshotId": "snap-234087fb",
    "CreateTime": "2020-11-20T19:54:05.000Z",
    "Size": 15
  }
]
```

要按索引查看数组中的特定卷，请调用数组索引。例如，`Volumes` 数组中的第一个项目的索引为 0，返回 `Volumes[0]` 查询。有关数组索引的更多信息，请参阅 *JMESPath 网站*上的[索引表达式](http://jmespath.org/specification.html#index-expressions)。

```
$ aws ec2 describe-volumes \
    --query 'Volumes[0]'
{
  "AvailabilityZone": "us-west-2a",
  "Attachments": [
    {
      "AttachTime": "2013-09-17T00:55:03.000Z",
      "InstanceId": "i-a071c394",
      "VolumeId": "vol-e11a5288",
      "State": "attached",
      "DeleteOnTermination": true,
      "Device": "/dev/sda1"
    }
  ],
  "VolumeType": "standard",
  "VolumeId": "vol-e11a5288",
  "State": "in-use",
  "SnapshotId": "snap-f23ec1c8",
  "CreateTime": "2013-09-17T00:55:03.000Z",
  "Size": 30
}
```

要按索引查看特定范围的卷，请使用 `slice` 与以下语法，其中 **start** 是起始数组索引，**stop** 是筛选条件停止处理的索引，而 **step** 是跳过间隔。

**语法**

```
<arrayName>[<start>:<stop>:<step>]
```

如果 Slice 表达式中忽略了其中任何一个，它们将使用以下默认值：
+ Start – 列表中的第一个索引，0。
+ Stop – 列表中的最后一个索引。
+ Step – 没有跳过步骤，其中值为 1。

要仅返回前两个卷，请使用起始值 0、停止值 2 和步长值 1，如以下示例所示。

```
$ aws ec2 describe-volumes \
    --query 'Volumes[0:2:1]'
[
  {
    "AvailabilityZone": "us-west-2a",
    "Attachments": [
      {
        "AttachTime": "2013-09-17T00:55:03.000Z",
        "InstanceId": "i-a071c394",
        "VolumeId": "vol-e11a5288",
        "State": "attached",
        "DeleteOnTermination": true,
        "Device": "/dev/sda1"
      }
    ],
    "VolumeType": "standard",
    "VolumeId": "vol-e11a5288",
    "State": "in-use",
    "SnapshotId": "snap-f23ec1c8",
    "CreateTime": "2013-09-17T00:55:03.000Z",
    "Size": 30
  },
  {
    "AvailabilityZone": "us-west-2a",
    "Attachments": [
      {
        "AttachTime": "2013-09-18T20:26:16.000Z",
        "InstanceId": "i-4b41a37c",
        "VolumeId": "vol-2e410a47",
        "State": "attached",
        "DeleteOnTermination": true,
        "Device": "/dev/sda1"
      }
    ],
    "VolumeType": "standard",
    "VolumeId": "vol-2e410a47",
    "State": "in-use",
    "SnapshotId": "snap-708e8348",
    "CreateTime": "2013-09-18T20:26:15.000Z",
    "Size": 8
  }
]
```

由于此示例包含默认值，因此您可以将 Slice 从 `Volumes[0:2:1]` 缩短到 `Volumes[:2]`。

以下示例省略了默认值，并返回整个数组中的每两个卷。

```
$ aws ec2 describe-volumes \
    --query 'Volumes[::2]'
[
  {
    "AvailabilityZone": "us-west-2a",
    "Attachments": [
      {
        "AttachTime": "2013-09-17T00:55:03.000Z",
        "InstanceId": "i-a071c394",
        "VolumeId": "vol-e11a5288",
        "State": "attached",
        "DeleteOnTermination": true,
        "Device": "/dev/sda1"
      }
    ],
    "VolumeType": "standard",
    "VolumeId": "vol-e11a5288",
    "State": "in-use",
    "SnapshotId": "snap-f23ec1c8",
    "CreateTime": "2013-09-17T00:55:03.000Z",
    "Size": 30
  },
  {
    "AvailabilityZone": "us-west-2a",
    "Attachments": [
      {
        "AttachTime": "2020-11-20T19:54:06.000Z",
        "InstanceId": "i-1jd73kv8",
        "VolumeId": "vol-a1b3c7nd",
        "State": "attached",
        "DeleteOnTermination": true,
        "Device": "/dev/sda1"
      }
    ],
    "VolumeType": "standard",
    "VolumeId": "vol-a1b3c7nd",
    "State": "in-use",
    "SnapshotId": "snap-234087fb",
    "CreateTime": "2020-11-20T19:54:05.000Z",
    "Size": 15
  }
]
```

Steps 还可以使用负数按数组的相反顺序进行筛选，如以下示例所示。

```
$ aws ec2 describe-volumes \
    --query 'Volumes[::-2]'
[
  {
    "AvailabilityZone": "us-west-2a",
    "Attachments": [
      {
        "AttachTime": "2020-11-20T19:54:06.000Z",
        "InstanceId": "i-1jd73kv8",
        "VolumeId": "vol-a1b3c7nd",
        "State": "attached",
        "DeleteOnTermination": true,
        "Device": "/dev/sda1"
      }
    ],
    "VolumeType": "standard",
    "VolumeId": "vol-a1b3c7nd",
    "State": "in-use",
    "SnapshotId": "snap-234087fb",
    "CreateTime": "2020-11-20T19:54:05.000Z",
    "Size": 15
  },
  {
    "AvailabilityZone": "us-west-2a",
    "Attachments": [
      {
        "AttachTime": "2013-09-17T00:55:03.000Z",
        "InstanceId": "i-a071c394",
        "VolumeId": "vol-e11a5288",
        "State": "attached",
        "DeleteOnTermination": true,
        "Device": "/dev/sda1"
      }
    ],
    "VolumeType": "standard",
    "VolumeId": "vol-e11a5288",
    "State": "in-use",
    "SnapshotId": "snap-f23ec1c8",
    "CreateTime": "2013-09-17T00:55:03.000Z",
    "Size": 30
  }
]
```

有关更多信息，请参阅 *JMESPath 网站*上的 [Slices](https://jmespath.org/specification.html#slices)。

### 筛选嵌套数据
<a name="cli-usage-filter-client-side-nested"></a>

要缩小嵌套值 `Volumes[*]` 的筛选范围，您可以通过附加句点和筛选条件来使用子表达式。

**语法**

```
<expression>.<expression>
```

以下示例显示了所有卷的所有 `Attachments` 信息。

```
$ aws ec2 describe-volumes \
    --query 'Volumes[*].Attachments'
[
  [
    {
      "AttachTime": "2013-09-17T00:55:03.000Z",
      "InstanceId": "i-a071c394",
      "VolumeId": "vol-e11a5288",
      "State": "attached",
      "DeleteOnTermination": true,
      "Device": "/dev/sda1"
    }
  ],
  [
    {
      "AttachTime": "2013-09-18T20:26:16.000Z",
      "InstanceId": "i-4b41a37c",
      "VolumeId": "vol-2e410a47",
      "State": "attached",
      "DeleteOnTermination": true,
      "Device": "/dev/sda1"
    }
  ],
  [
    {
      "AttachTime": "2020-11-20T19:54:06.000Z",
      "InstanceId": "i-1jd73kv8",
      "VolumeId": "vol-a1b3c7nd",
      "State": "attached",
      "DeleteOnTermination": true,
      "Device": "/dev/sda1"
    }
  ]
]
```

要进一步筛选嵌套值，请为每个嵌套标识符附加表达式。以下示例列出了所有 `State` 的 `Volumes`。

```
$ aws ec2 describe-volumes \
    --query 'Volumes[*].Attachments[*].State'
[
  [
    "attached"
  ],
  [
    "attached"
  ],
  [
    "attached"
  ]
]
```

### 展平结果
<a name="cli-usage-filter-client-side-specific-flattening"></a>

有关更多信息，请参阅 *JMESPath 网站*上的 [SubExpressions](https://jmespath.org/specification.html#subexpressions)。

您可以通过删除导致 `Volumes[*].Attachments[*].State` 查询的通配符表示法来展平 `Volumes[*].Attachments[].State` 的结果。展平操作通常有助于提高结果的可读性。

```
$ aws ec2 describe-volumes \
    --query 'Volumes[*].Attachments[].State'
[
  "attached",
  "attached",
  "attached"
]
```

有关更多信息，请参阅 *JMESPath 网站*上的[展平](https://jmespath.org/specification.html#flatten)。

### 筛选特定值
<a name="cli-usage-filter-client-side-specific-values"></a>

要筛选列表中的特定值，可以使用筛选条件表达式，如以下语法所示。

**语法**

```
? <expression> <comparator> <expression>]
```

表达式比较器包括 `==`、`!=`、`<`、`<=`、`>` 和 `>=`。以下示例为 `VolumeIds``Volumes` 中的所有 `Attached` 筛选 `State`。

```
$ aws ec2 describe-volumes \
    --query 'Volumes[*].Attachments[?State==`attached`].VolumeId'
[
  [
    "vol-e11a5288"
  ],
  [
    "vol-2e410a47"
  ],
  [
    "vol-a1b3c7nd"
  ]
]
```

然后可以将其展平，从而生成以下示例。

```
$ aws ec2 describe-volumes \
    --query 'Volumes[*].Attachments[?State==`attached`].VolumeId[]'
[
  "vol-e11a5288",
  "vol-2e410a47",
  "vol-a1b3c7nd"
]
```

以下示例筛选了尺寸小于 20 的所有 `VolumeIds` 的 `Volumes`。

```
$ aws ec2 describe-volumes \
    --query 'Volumes[?Size < `20`].VolumeId'
[
  "vol-2e410a47",
  "vol-a1b3c7nd"
]
```

有关更多信息，请参阅 *JMESPath 网站*上的[筛选表达式](https://jmespath.org/specification.html#filterexpressions)。

### 传输表达式
<a name="cli-usage-filter-client-side-pipe"></a>

您可以将筛选器的结果传输到新列表中，然后通过以下语法使用另一个表达式筛选结果：

**语法**

```
<expression> | <expression>] 
```

以下示例获取 `Volumes[*].Attachments[].InstanceId` 表达式的筛选结果并在数组中输出第一个结果。

```
$ aws ec2 describe-volumes \
    --query 'Volumes[*].Attachments[].InstanceId | [0]'
"i-a071c394"
```

本示例首先通过以下表达式创建数组来实现此目的。

```
$ aws ec2 describe-volumes \
    --query 'Volumes[*].Attachments[].InstanceId'
"i-a071c394",
  "i-4b41a37c",
  "i-1jd73kv8"
```

然后返回该数组中的第一个元素。

```
"i-a071c394"
```

有关更多信息，请参阅 *JMESPath 网站*上的[传输表达式](https://jmespath.org/specification.html#pipe-expressions)。

### 筛选多个标识符值
<a name="cli-usage-filter-client-side-miltiselect-list"></a>

要筛选多个标识符，您可以使用以下语法使用多选列表：

**语法**

```
<listName>[].[<expression>, <expression>]
```

在以下示例中，`VolumeId` 和 `VolumeType` 在 `Volumes` 列表中进行筛选，生成以下表达式。

```
$ aws ec2 describe-volumes \
    --query 'Volumes[].[VolumeId, VolumeType]'
[
  [
    "vol-e11a5288",
    "standard"
  ],
  [
    "vol-2e410a47",
    "standard"
  ],
  [
    "vol-a1b3c7nd",
    "standard"
  ]
]
```

要将嵌套数据添加到列表中，请添加另一个多选列表。下面的示例通过在嵌套 `InstanceId` 列表中筛选 `State` 和 `Attachments` 在上一个示例中进行了扩展。这将产生以下表达式。

```
$ aws ec2 describe-volumes \
    --query 'Volumes[].[VolumeId, VolumeType, Attachments[].[InstanceId, State]]'
[
  [
    "vol-e11a5288",
    "standard",
    [
      [
        "i-a071c394",
        "attached"
      ]
    ]
  ],
  [
    "vol-2e410a47",
    "standard",
    [
      [
        "i-4b41a37c",
        "attached"
      ]
    ]
  ],
  [
    "vol-a1b3c7nd",
    "standard",
    [
      [
        "i-1jd73kv8",
        "attached"
      ]
    ]
  ]
]
```

为了更具可读性，请按以下示例所示展开表达式。

```
$ aws ec2 describe-volumes \
    --query 'Volumes[].[VolumeId, VolumeType, Attachments[].[InstanceId, State][]][]'
[
  "vol-e11a5288",
  "standard",
  [
    "i-a071c394",
    "attached"
  ],
  "vol-2e410a47",
  "standard",
  [
    "i-4b41a37c",
    "attached"
  ],
  "vol-a1b3c7nd",
  "standard",
  [
    "i-1jd73kv8",
    "attached"
  ]
]
```

有关更多信息，请参阅 *JMESPath 网站*上的[多选列表](https://jmespath.org/specification.html#multiselectlist)。

### 将标签添加到标识符值
<a name="cli-usage-filter-client-side-multiselect-hash"></a>

为了使此输出更易于读取，请使用具有以下语法的多选哈希。

**语法**

```
<listName>[].{<label>: <expression>, <label>: <expression>}
```

您的标识符标签不必与标识符的名称相同。以下示例为 `VolumeType` 值使用标签 `VolumeType`。

```
$ aws ec2 describe-volumes \
    --query 'Volumes[].{VolumeType: VolumeType}'
[
  {
    "VolumeType": "standard",
  },
  {
    "VolumeType": "standard",
  },
  {
    "VolumeType": "standard",
  }
]
```

为简单起见，以下示例保留每个标签的标识符名称，并显示所有卷的 `VolumeId`、`VolumeType`、`InstanceId` 和 `State`：

```
$ aws ec2 describe-volumes \
    --query 'Volumes[].{VolumeId: VolumeId, VolumeType: VolumeType, InstanceId: Attachments[0].InstanceId, State: Attachments[0].State}'
[
  {
    "VolumeId": "vol-e11a5288",
    "VolumeType": "standard",
    "InstanceId": "i-a071c394",
    "State": "attached"
  },
  {
    "VolumeId": "vol-2e410a47",
    "VolumeType": "standard",
    "InstanceId": "i-4b41a37c",
    "State": "attached"
  },
  {
    "VolumeId": "vol-a1b3c7nd",
    "VolumeType": "standard",
    "InstanceId": "i-1jd73kv8",
    "State": "attached"
  }
]
```

有关更多信息，请参阅 *JMESPath 网站* 上的[多选哈希](https://jmespath.org/specification.html#multiselecthash)。

### 函数
<a name="cli-usage-filter-client-side-functions"></a>

JMESPath 语法包含许多可用于查询的函数。有关 JMESPath 函数的信息，请参阅 *JMESPath 网站*上的[内置函数](https://jmespath.org/specification.html#built-in-functions)。

为了演示如何将函数合并到查询中，以下示例使用了 `sort_by` 函数。该 `sort_by` 函数使用以下语法将表达式作为排序键对数组进行排序：

**语法**

```
sort_by(<listName>, <sort expression>)[].<expression>
```

以下示例使用先前的[多选哈希示例](#cli-usage-filter-client-side-multiselect-hash)并按照 `VolumeId` 对输出进行排序。

```
$ aws ec2 describe-volumes \
    --query 'sort_by(Volumes, &VolumeId)[].{VolumeId: VolumeId, VolumeType: VolumeType, InstanceId: Attachments[0].InstanceId, State: Attachments[0].State}'
[
  {
    "VolumeId": "vol-2e410a47",
    "VolumeType": "standard",
    "InstanceId": "i-4b41a37c",
    "State": "attached"
  },
  {
    "VolumeId": "vol-a1b3c7nd",
    "VolumeType": "standard",
    "InstanceId": "i-1jd73kv8",
    "State": "attached"
  },
  {
    "VolumeId": "vol-e11a5288",
    "VolumeType": "standard",
    "InstanceId": "i-a071c394",
    "State": "attached"
  }
]
```

有关更多信息，请参阅 *JMESPath 网站*上的[排序依据](https://jmespath.org/specification.html#sort-by)。

### 高级 `--query` 示例
<a name="cli-usage-filter-client-side-advanced"></a>

**从特定项目中提取信息**

以下示例使用 `--query` 参数在列表中查找特定的项目，然后提取该项目的的信息。此示例列出了与指定的服务端点相关联的所有 `AvailabilityZones`。它从 `ServiceDetails` 列表中提取具有指定 `ServiceName` 的项目，然后输出该选定项目的 `AvailabilityZones` 字段。

```
$ aws --region us-east-1 ec2 describe-vpc-endpoint-services \
    --query 'ServiceDetails[?ServiceName==`com.amazonaws.us-east-1.ecs`].AvailabilityZones'
[
    [
        "us-east-1a",
        "us-east-1b",
        "us-east-1c",
        "us-east-1d",
        "us-east-1e",
        "us-east-1f"
    ]
]
```

**在指定创建日期之后显示快照**

以下示例显示如何列出在指定日期之后创建的所有快照，从而在输出中仅包括几个可用字段。

```
$ aws ec2 describe-snapshots --owner self \
    --output json \
    --query 'Snapshots[?StartTime>=`2018-02-07`].{Id:SnapshotId,VId:VolumeId,Size:VolumeSize}'
[
    {
        "id": "snap-0effb42b7a1b2c3d4",
        "vid": "vol-0be9bb0bf12345678",
        "Size": 8
    }
]
```

**显示最新 AMI**

以下示例列出了您创建的五个最新 Amazon 机器映像（AMI），从最新到最旧排序。

```
$ aws ec2 describe-images \
    --owners self \
    --query 'reverse(sort_by(Images,&CreationDate))[:5].{id:ImageId,date:CreationDate}'
[
    {
        "id": "ami-0a1b2c3d4e5f60001",
        "date": "2018-11-28T17:16:38.000Z"
    },
    {
        "id": "ami-0a1b2c3d4e5f60002",
        "date": "2018-09-15T13:51:22.000Z"
    },
    {
        "id": "ami-0a1b2c3d4e5f60003",
        "date": "2018-08-19T10:22:45.000Z"
    },
    {
        "id": "ami-0a1b2c3d4e5f60004",
        "date": "2018-05-03T12:04:02.000Z"
    },
    {
        "id": "ami-0a1b2c3d4e5f60005",
        "date": "2017-12-13T17:16:38.000Z"
    }
]
```

**显示运行状况不佳的 Auto Scaling 实例**

以下示例仅显示指定 Auto Scaling 组中任何运行状况不佳的实例的 `InstanceId`。

```
$ aws autoscaling describe-auto-scaling-groups \
    --auto-scaling-group-name My-AutoScaling-Group-Name \
    --output text \
    --query 'AutoScalingGroups[*].Instances[?HealthStatus==`Unhealthy`].InstanceId'
```

**包括带指定标签的卷**

以下示例描述了所有带 `test` 标签的实例。只要附加的卷旁边 `test` 还有另一个标签，那么结果中仍会返回该卷。

下面的表达式在数组中返回带 `test` 标签的所有标签。任何不是 `test` 标签的标签都包含 `null` 值。

```
$ aws ec2 describe-volumes \
    --query 'Volumes[*].Tags[?Value == `test`]'
```

**排除具有指定标签的卷**

以下示例描述了所有不带 `test` 标签的实例。使用简单 `?Value != `test`` 表达式不适用于排除卷，因为卷可能有多个标签。只要附加的卷旁边 `test` 还有另一个标签，那么结果中仍会返回该卷。

要排除带有 `test`标签的所有卷，请从下面的表达式开始返回数组中带有该 `test` 标签的所有标签。任何不是 `test` 标签的标签都包含 `null` 值。

```
$ aws ec2 describe-volumes \
    --query 'Volumes[*].Tags[?Value == `test`]'
```

然后使用 `test` 函数筛选掉所有正数 `not_null` 结果。

```
$ aws ec2 describe-volumes \
    --query 'Volumes[?!not_null(Tags[?Value == `test`].Value)]'
```

传输结果以展开会导致以下查询的结果。

```
$ aws ec2 describe-volumes \
    --query 'Volumes[?!not_null(Tags[?Value == `test`].Value)] | []'
```

## 结合服务器端和客户端筛选
<a name="cli-usage-filter-combining"></a>

您可以同时使用服务器端和客户端筛选。首先完成服务器端筛选，将数据发送到客户端，然后由 `--query` 参数进行筛选。如果您使用的是大型数据集，首先使用服务器端筛选可以降低每次 AWS CLI 调用发送给客户端的数据量，同时仍保持客户端筛选提供的强大自定义功能。

以下示例列出了使用服务器端和客户端筛选的 Amazon EC2 卷。该服务在 `us-west-2a` 可用区中筛选所有附加的卷的列表。`--query` 参数进一步将输出限制为只有 `Size` 值大于 50 的卷，并且仅显示具有用户定义名称的指定字段。

```
$ aws ec2 describe-volumes \
    --filters "Name=availability-zone,Values=us-west-2a" "Name=status,Values=attached" \
    --query 'Volumes[?Size > `50`].{Id:VolumeId,Size:Size,Type:VolumeType}'
[
    {
        "Id": "vol-0be9bb0bf12345678",
        "Size": 80,
        "VolumeType": "gp2"
    }
]
```

以下示例检索满足多个条件的镜像的列表。然后，它使用 `--query` 参数按 `CreationDate` 对输出进行排序，从而仅选择最新的。最终，它显示这一个镜像的 `ImageId`。

```
$ aws ec2 describe-images \
    --owners amazon \
    --filters "Name=name,Values=amzn*gp2" "Name=virtualization-type,Values=hvm" "Name=root-device-type,Values=ebs" \
    --query "sort_by(Images, &CreationDate)[-1].ImageId" \
    --output text
ami-00ced3122871a4921
```

以下示例通过使用 `length` 计算列表中的数量，以显示超过 1000 IOPS 的可用卷数。

```
$ aws ec2 describe-volumes \
    --filters "Name=status,Values=available" \
    --query 'length(Volumes[?Iops > `1000`])'
3
```

以下示例检索在指定的 AWS 区域中使用启动配置（这些配置使用 CloudFormation 堆栈）的自动扩缩组的名称。

```
$ aws autoscaling describe-auto-scaling-groups --region us-west-2 \
  --filters Name=tag-key,Values=aws:cloudformation:stack-name \
  --query 'AutoScalingGroups[?LaunchConfigurationName!=`null`].AutoScalingGroupName'
[
    "group-1",
    "group-2",
    "group-3"
]
```

## 其他资源
<a name="cli-usage-filter-resources"></a>

**JMESPath 终端**  
JMESPath 终端是一个交互式终端命令，以试验用于客户端筛选的 JMESPath 表达式。使用 `jpterm` 命令，终端会在您键入时显示即时查询结果。您可以直接将 AWS CLI 输出传输到终端，从而启用高级查询试验。  
以下示例将 `aws ec2 describe-volumes` 输出直接传输到 JMESPath 终端。  

```
$ aws ec2 describe-volumes | jpterm
```
有关 JMESPath 终端和安装说明的更多信息，请参阅 *GitHub* 上的 [JMESPath 终端](https://github.com/jmespath/jmespath.terminal)。

**jq 实用工具**  
该 `jq` 实用工具为您提供了一种将客户端输出转换为所需输出格式的方法。有关 `jq` 和安装说明的更多信息，请参阅 *GitHub* 上的 [jq](https://stedolan.github.io/jq/)。