

# 在 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/latest/reference/ses/create-receipt-filter.html) 和 [ce](https://docs.aws.amazon.com/cli/latest/reference/ce/get-cost-and-usage.html)。
+ `--filters`，例如 [ec2](https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-volumes.html)、[autoscaling](https://docs.aws.amazon.com/cli/latest/reference/autoscaling/describe-tags.html) 和 [rds](https://docs.aws.amazon.com/cli/latest/reference/rds/describe-db-instances.html)。
+ 以单词 `filter` 开头的名称，例如 `--filter-expression` 用于 [https://docs.aws.amazon.com/cli/latest/reference/dynamodb/scan.html](https://docs.aws.amazon.com/cli/latest/reference/dynamodb/scan.html) 命令。

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

## 客户端筛选
<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`、 `--output yaml` 或 `--output yaml-stream`，则在应用 `--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>

**AWS CLI 自动提示**  
开始使用筛选条件表达式时，您可以使用 AWS CLI 版本 2 中的自动提示功能。按 **F5** 键时，自动提示功能提供预览。有关更多信息，请参阅 [在 AWS CLI 中启用和使用命令提示符](cli-usage-parameters-prompting.md)。

**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/)。