

# Controlling command output in the AWS CLI
<a name="cli-usage-output"></a>

This section describes the different ways to control the output from the AWS Command Line Interface (AWS CLI). Customizing the AWS CLI output in your terminal can improve readability, streamline scripting automation and provide easier navigation through larger data sets.

The AWS CLI supports multiple [output formats](cli-usage-output-format.md), including [`json`](cli-usage-output-format.md#json-output), [`text`](cli-usage-output-format.md#text-output), [`yaml`](cli-usage-output-format.md#yaml-output), [`off`](cli-usage-output-format.md#off-output), and [`table`](cli-usage-output-format.md#table-output). Some services have server-side [pagination](cli-usage-pagination.md) for their data and the AWS CLI provides it's own client-side features for additional pagination options.

Lastly, the AWS CLI has both[ server-side and client-side filtering](cli-usage-filter.md) that you can use individually or together to filter your AWS CLI output.

**Topics**
+ [Sensitive output](#cli-usage-output-sensitive)
+ [Server-side vs client-side output options](#cli-usage-output-server-client)
+ [Setting the output format in the AWS CLI](cli-usage-output-format.md)
+ [Structured error output in the AWS CLI](cli-usage-error-format.md)
+ [Using the pagination options in the AWS CLI](cli-usage-pagination.md)
+ [Filtering output in the AWS CLI](cli-usage-filter.md)

## Sensitive output
<a name="cli-usage-output-sensitive"></a>

Some operations of the AWS CLI might return information that could be considered sensitive, including information from environment variables. The exposure of this information might represent a security risk in certain scenarios; for example, the information could be included in continuous integration and continuous deployment (CI/CD) logs. It is therefore important that you review when you are including such output as part of your logs, and suppress the output when not needed.

For additional information about protecting sensitive data, see [Data protection in the AWS CLI](data-protection.md).

Consider the following best practices:
+ Consider programmatically retrieving your secrets from a secrets store, such as AWS Secrets Manager.
+ Review the contents of your build logs to ensure they do not contain sensitive information. Consider approaches such as piping to `/dev/null` or capturing the output as a bash or PowerShell variable to suppress command outputs. 

  The following is a bash example for redirecting output, but not errors, to `/dev/null`:

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

  For specifics on suppressing output for your terminal, see the user documentation of the terminal you use.
+ Consider the access of your logs and scope the access appropriately for your use case.

## Server-side vs client-side output options
<a name="cli-usage-output-server-client"></a>

The AWS CLI has both[ server-side and client-side filtering](cli-usage-filter.md) that you can use individually or together to filter your AWS CLI output. Server-side filtering is processed first and returns your output for client-side filtering. Server-side filtering is supported by the service API. Client-side filtering is supported by the AWS CLI client using the `--query` parameter.

**Server-side** output options are features directly supported by the AWS service API. Any data that is filtered or paged out is not sent to the client, which can speed up HTTP response times and improve bandwidth for larger data sets.

**Client-side** output options are features created by the AWS CLI. All data is sent to the client, then the AWS CLI filters or pages the content displayed. Client-side operations do not save on speed or bandwidth for larger datasets.

When server-side and client-side options are used together, server-side operations are completed first and then sent to the client for client-side operations. This uses the potential speed and bandwidth savings of server-side options, while using additional AWS CLI features to get your desired output.

# Setting the output format in the AWS CLI
<a name="cli-usage-output-format"></a>

This topic describes the different output formats for the AWS Command Line Interface (AWS CLI). The AWS CLI supports the following output formats:
+ **[`json`](#json-output)** – The output is formatted as a [JSON](https://json.org/) string.
+  **[`yaml`](#yaml-output)** – The output is formatted as a [YAML](https://yaml.org/) string.
+ **[`yaml-stream`](#yaml-stream-output)** – The output is streamed and formatted as a [YAML](https://yaml.org/) string. Streaming allows for faster handling of large data types.
+ **[`text`](#text-output)** – The output is formatted as multiple lines of tab-separated string values. This can be useful to pass the output to a text processor, like `grep`, `sed`, or `awk`.
+ **[`table`](#table-output)** – The output is formatted as a table using the characters \$1\$1- to form the cell borders. It typically presents the information in a "human-friendly" format that is much easier to read than the others, but not as programmatically useful.
+ **[`off`](#off-output)** – The output suppresses all command output to stdout. This is useful in automation scripts and CI/CD pipelines where you only need to check the command's exit code without processing the output.

## How to select the output format
<a name="cli-usage-output-format-how"></a>

As explained in the [configuration](cli-chap-configure.md) topic, you can specify the output format in three ways:
+ **Using the `output` option in a named profile in the `config` file** – The following example sets the default output format to `text`.

  ```
  [default]
  output=text
  ```
+ **Using the `AWS_DEFAULT_OUTPUT` environment variable** – The following output sets the format to `table` for the commands in this command line session until the variable is changed or the session ends. Using this environment variable overrides any value set in the `config` file.

  ```
  $ export AWS_DEFAULT_OUTPUT="table"
  ```
+ **Using the `--output` option on the command line ** – The following example sets the output of only this one command to `json`. Using this option on the command overrides any currently set environment variable or the value in the `config` file.

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

**Important**  
The output type you specify changes how the `--query` option operates:  
If you specify `--output text`, the output is paginated *before* the `--query` filter is applied, and the AWS CLI runs the query once on *each page* of the output. Due to this, the query includes the first matching element on each page which can result in unexpected extra output. To additionally filter the output, you can use other command line tools such as `head` or `tail`.
If you specify `--output json`, `--output yaml`, or `--output yaml-stream` the output is completely processed as a single, native structure before the `--query` filter is applied. The AWS CLI runs the query only once against the entire structure, producing a filtered result that is then output.

## JSON output format
<a name="json-output"></a>

[JSON](https://json.org) is the default output format of the AWS CLI. Most programming languages can easily decode JSON strings using built-in functions or with publicly available libraries. You can combine JSON output with the [--query option](cli-usage-filter.md) in powerful ways to filter and format the AWS CLI JSON-formatted output. 

For more advanced filtering that you might not be able to do with `--query`, you can consider `jq`, a command line JSON processor. You can download it and find the official tutorial at [http://stedolan.github.io/jq/](http://stedolan.github.io/jq/).

The following is an example of JSON output.

```
$ 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"
        }
    ]
}
```

## YAML output format
<a name="yaml-output"></a>

[YAML](https://yaml.org) is a good choice for handling the output programmatically with services and tools that emit or consume [YAML](https://yaml.org)-formatted strings, such as CloudFormation with its support for [YAML-formatted templates](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-formats.html).

For more advanced filtering that you might not be able to do with `--query`, you can consider `yq`, a command line YAML processor. You can download `yq` in the [yq repository](https://github.com/mikefarah/yq) on *GitHub*.

The following is an example of YAML output.

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

```
Users:
- Arn: arn:aws:iam::123456789012:user/Admin
  CreateDate: '2014-10-16T16:03:09+00:00'
  PasswordLastUsed: '2016-06-03T18:37:29+00:00'
  Path: /
  UserId: AIDA1111111111EXAMPLE
  UserName: Admin
- Arn: arn:aws:iam::123456789012:user/backup/backup-user
  CreateDate: '2019-09-17T19:30:40+00:00'
  Path: /backup/
  UserId: AIDA2222222222EXAMPLE
  UserName: arq-45EFD6D1-CE56-459B-B39F-F9C1F78FBE19
- Arn: arn:aws:iam::123456789012:user/cli-user
  CreateDate: '2019-09-17T19:30:40+00:00'
  Path: /
  UserId: AIDA3333333333EXAMPLE
  UserName: cli-user
```

## YAML stream output format
<a name="yaml-stream-output"></a>

The `yaml-stream` format takes advantage of the [YAML](https://yaml.org) format while providing more responsive/faster viewing of large data sets by streaming the data to you. You can start viewing and using YAML data before the entire query downloads. 

For more advanced filtering that you might not be able to do with `--query`, you can consider `yq`, a command line YAML processor. You can download `yq` in the [yq repository](https://github.com/mikefarah/yq) on *GitHub*.

The following is an example of `yaml-stream` output.

```
$ aws iam list-users --output yaml-stream
```

```
- IsTruncated: false
  Users:
  - Arn: arn:aws:iam::123456789012:user/Admin
    CreateDate: '2014-10-16T16:03:09+00:00'
    PasswordLastUsed: '2016-06-03T18:37:29+00:00'
    Path: /
    UserId: AIDA1111111111EXAMPLE
    UserName: Admin
  - Arn: arn:aws:iam::123456789012:user/backup/backup-user
    CreateDate: '2019-09-17T19:30:40+00:00'
    Path: /backup/
    UserId: AIDA2222222222EXAMPLE
    UserName: arq-45EFD6D1-CE56-459B-B39F-F9C1F78FBE19
  - Arn: arn:aws:iam::123456789012:user/cli-user
    CreateDate: '2019-09-17T19:30:40+00:00'
    Path: /
    UserId: AIDA3333333333EXAMPLE
    UserName: cli-user
```

The following is an example of `yaml-stream` output in conjunction with using the `--page-size` parameter to paginate the streamed YAML content.

```
$ aws iam list-users --output yaml-stream --page-size 2
```

```
- IsTruncated: true
  Marker: ab1234cdef5ghi67jk8lmo9p/q012rs3t445uv6789w0x1y2z/345a6b78c9d00/1efgh234ij56klmno78pqrstu90vwxyx  
  Users:
  - Arn: arn:aws:iam::123456789012:user/Admin
    CreateDate: '2014-10-16T16:03:09+00:00'
    PasswordLastUsed: '2016-06-03T18:37:29+00:00'
    Path: /
    UserId: AIDA1111111111EXAMPLE
    UserName: Admin
  - Arn: arn:aws:iam::123456789012:user/backup/backup-user
    CreateDate: '2019-09-17T19:30:40+00:00'
    Path: /backup/
    UserId: AIDA2222222222EXAMPLE
    UserName: arq-45EFD6D1-CE56-459B-B39F-F9C1F78FBE19
- IsTruncated: false
  Users:
  - Arn: arn:aws:iam::123456789012:user/cli-user
    CreateDate: '2019-09-17T19:30:40+00:00'
    Path: /
    UserId: AIDA3333333333EXAMPLE
    UserName: cli-user
```

## Text output format
<a name="text-output"></a>

The `text` format organizes the AWS CLI output into tab-delimited lines. It works well with traditional Unix text tools such as `grep`, `sed`, and `awk`, and the text processing performed by PowerShell. 

The `text` output format follows the basic structure shown below. The columns are sorted alphabetically by the corresponding key names of the underlying JSON object.

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

The following is an example of `text` output. Each field is tab separated from the others, with an extra tab where there is an empty field.

```
$ 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
```

The fourth column is the `PasswordLastUsed` field, and is empty for the last two entries because those users never sign in to the AWS Management Console.

**Important**  
*We strongly recommend that if you specify `text` output, you also always use the [`--query`](cli-usage-filter.md) option to ensure consistent behavior*.   
This is because the text format alphabetically orders output columns by the key name of the underlying JSON object returned by the AWS service, and similar resources might not have the same key names. For example, the JSON representation of a Linux-based Amazon EC2 instance might have elements that are not present in the JSON representation of a Windows-based instance, or vice versa. Also, resources might have key-value elements added or removed in future updates, altering the column ordering. This is where `--query` augments the functionality of the `text` output to provide you with complete control over the output format.   
In the following example, the command specifies which elements to display and *defines the ordering* of the columns with the list notation `[key1, key2, ...]`. This gives you full confidence that the correct key values are always displayed in the expected column. Finally, notice how the AWS CLI outputs `None` as the value for keys that don't exist.  

```
$ 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
```

The following example shows how you can use `grep` and `awk` with the `text` output from the `aws ec2 describe-instances` command. The first command displays the Availability Zone, current state, and the instance ID of each instance in `text` output. The second command processes that output to display only the instance IDs of all running instances in the `us-west-2a` Availability Zone.

```
$ 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
```

The following example goes a step further and shows not only how to filter the output, but how to use that output to automate changing instance types for each stopped instance.

```
$ 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
```

The `text` output can also be useful in PowerShell. Because the columns in `text` output are tab delimited, you can easily split the output into an array by using PowerShell's ``t` delimiter. The following command displays the value of the third column (`InstanceId`) if the first column (`AvailabilityZone`) matches the string `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
```

Notice that although the previous example does show how to use the `--query` parameter to parse the underlying JSON objects and pull out the desired column, PowerShell has its own ability to handle JSON, if cross-platform compatibility isn't a concern. Instead of handling the output as text, as most command shells require, PowerShell lets you use the `ConvertFrom-JSON` cmdlet to produce a hierarchically structured object. You can then directly access the member you want from that object.

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

**Tip**  
If you output text, and filter the output to a single field using the `--query` parameter, the output is a single line of tab-separated values. To get each value onto a separate line, you can put the output field in brackets, as shown in the following examples.  
Tab separated, single-line output:  

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

```
HRDepartment    Developers      SpreadsheetUsers  LocalAdmins
```
Each value on its own line by putting `[GroupName]` in brackets:  

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

```
HRDepartment
Developers
SpreadsheetUsers
LocalAdmins
```

## Table output format
<a name="table-output"></a>

The `table` format produces human-readable representations of complex AWS CLI output in a tabular form.

```
$ 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    ||
+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
```

You can combine the `--query` option with the `table` format to display a set of elements preselected from the raw output. Notice the output differences between dictionary and list notations: in the first example, column names are ordered alphabetically, and in the second example, unnamed columns are ordered as defined by the user. For more information about the `--query` option, see [Filtering output in the 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  |
+--------------+--------------+--------------+-----+
```

## Off output format
<a name="off-output"></a>

The `off` format suppresses all command output to stdout. This is useful in automation scripts and CI/CD pipelines where you only need to check the command's exit code without processing the output. Error messages are still displayed on stderr.

The following example shows how the `off` format suppresses successful output. You can check the exit code to determine success:

```
$ aws s3api list-buckets --output off
$ echo $?
0
```

This is particularly useful in shell scripts where you want to verify a resource exists without capturing output:

```
#!/bin/bash
if aws s3api head-bucket --bucket my-bucket --output off 2>/dev/null; then
    echo "Bucket exists"
else
    echo "Bucket does not exist"
fi
```

**Note**  
The `off` format only suppresses stdout. Errors are still written to stderr.

# Structured error output in the AWS CLI
<a name="cli-usage-error-format"></a>

This topic describes the structured error output formats for the AWS Command Line Interface (AWS CLI). The CLI writes errors to stderr and supports the following formats:
+ **[`enhanced`](#cli-error-format-enhanced)** (default) – Error message with additional details displayed inline. Use for human-readable debugging.
+ **[`json`](#cli-error-format-json)** – The output is formatted as a [JSON](https://json.org/) string with all error fields. Use for automation and scripting.
+ **[`yaml`](#cli-error-format-yaml)** – The output is formatted as a [YAML](https://yaml.org/) string with all error fields. Use for automation and scripting.
+ **[`text`](#cli-error-format-text)** – Formats errors using the text formatter. Use for quick visual scanning.
+ **[`table`](#cli-error-format-table)** – Formats errors using the table formatter. Use for quick visual scanning.
+ **[`legacy`](#cli-error-format-legacy)** – Original error format without structured details. Use for backward compatibility.

## Configuring error format
<a name="cli-error-format-configuring"></a>

You can configure the error format using any of the following methods:

Command-line flag  

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

Configuration file (`~/.aws/config`)  

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

Environment variable  

```
$ export AWS_CLI_ERROR_FORMAT=yaml
```

## Error output formats
<a name="cli-error-output-formats"></a>

The following sections describe each format:

### Enhanced format (default)
<a name="cli-error-format-enhanced"></a>

The enhanced format displays error messages with additional details inline for simple values. For complex structures, the format provides a hint to use JSON or YAML.

**Example: Missing region configuration**

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

**Example: Nonexistent Lambda function with additional fields**

```
aws: [ERROR]: An error occurred (ResourceNotFoundException) when calling the GetFunction operation: Function not found: arn:aws:lambda:us-west-2:123456789012:function:nonexistent-function-12345

Additional error details:
Type: User
```

The "Additional error details" section displays only fields that are defined in the service's error shape model. Unmodeled fields from the error response are not shown.

**Example: Complex error fields**

```
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 format
<a name="cli-error-format-json"></a>

The JSON format provides a structured representation with all error fields.

**Example: Missing region configuration**

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

**Example: Nonexistent Lambda function**

```
{
    "Code": "ResourceNotFoundException",
    "Message": "Function not found: arn:aws:lambda:us-west-2:123456789012:function:nonexistent-function-12345",
    "Type": "User"
}
```

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

The YAML format provides a structured representation with all error fields.

**Example: Missing region configuration**

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

**Example: Nonexistent Lambda function**

```
Code: ResourceNotFoundException
Message: "Function not found: arn:aws:lambda:us-west-2:123456789012:function:nonexistent-function-12345"
Type: User
```

### Text format
<a name="cli-error-format-text"></a>

The text format uses the same formatter as successful command output.

**Example: Nonexistent Lambda function**

```
ResourceNotFoundException    Function not found: arn:aws:lambda:us-west-2:123456789012:function:nonexistent-function-12345    User
```

### Table format
<a name="cli-error-format-table"></a>

The table format uses the same formatter as successful command output.

**Example: Nonexistent Lambda function**

```
------------------------------------------------------------------------------------------------------------------------------------|
|                                                              error                                                                 |
+----------------------------+--------------------------------------------------------------------------------------------------+------+
|            Code            |                              Message                                                             | Type |
+----------------------------+--------------------------------------------------------------------------------------------------+------+
|  ResourceNotFoundException |  Function not found: arn:aws:lambda:us-west-2:123456789012:function:nonexistent-function-12345   | User |
+----------------------------+--------------------------------------------------------------------------------------------------+------+
```

### Legacy format
<a name="cli-error-format-legacy"></a>

The legacy format provides the original error format without structured details. This format does not include the "An error occurred (ErrorCode):" prefix for CLI exceptions.

**Example: Missing region configuration**

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

**Example: Nonexistent Lambda function**

```
An error occurred (ResourceNotFoundException) when calling the GetFunction operation: Function not found: arn:aws:lambda:us-west-2:123456789012:function:nonexistent-function-12345
```

**Note**  
Errors now consistently include the `aws: [ERROR]:` prefix for CLI exceptions. Earlier versions did not always include this prefix.  
The following exceptions always use the legacy format regardless of the configured error format:  
`UnknownArgumentError` – Displays usage information
Keyboard interrupts (`KeyboardInterrupt`)

## Complete example
<a name="cli-error-format-example"></a>

The following example shows a command with JSON error formatting:

```
$ aws lambda get-function \
    --function-name nonexistent-function-12345 \
    --cli-error-format json
```

Output (stderr):

```
{
    "Code": "ResourceNotFoundException",
    "Message": "Function not found: arn:aws:lambda:us-west-2:123456789012:function:nonexistent-function-12345",
    "Type": "User"
}
```

The `Type` field is a modeled error member defined in the Lambda service's error shape. Only fields defined in the service's error model are included in the structured error output.

# Using the pagination options in the AWS CLI
<a name="cli-usage-pagination"></a>

This topic describes the different ways to paginate output from the AWS Command Line Interface (AWS CLI). 

There are primarily two ways to control pagination from the AWS CLI.
+ [Using server-side pagination parameters.](#cli-usage-pagination-serverside)
+ [Using your default output client-side paging program](#cli-usage-pagination-clientside).

Server-side pagination parameters process first and any output is sent to client-side pagination.

## Server-side pagination
<a name="cli-usage-pagination-serverside"></a>

For most commands that return a large list of items, the AWS CLI has multiple server-side options to control the number of items included in the output when the AWS CLI calls a service's API to populate the list. Server-side pagination in the AWS CLI is enabled by the AWS service API, therefore these options only work if the service API enables them.

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

By default, the AWS CLI uses a page size determined by the individual service and retrieves all available items. For example, Amazon S3 has a default page size of 1000. If you run `aws s3api list-objects` on an Amazon S3 bucket that contains 3,500 objects, the AWS CLI automatically makes four calls to Amazon S3, handling the service-specific pagination logic for you in the background and returning all 3,500 objects in the final output.

For information about whether a specific command has server-side pagination, see the [AWS CLI version 2 reference guide](https://docs.aws.amazon.com/cli/latest/reference/index.html).

### How to use the --no-paginate parameter
<a name="cli-usage-pagination-nopaginate"></a>

The `--no-paginate` option disables following pagination tokens on the client side. When using a command, by default the AWS CLI automatically makes multiple calls to return all possible results to create pagination. One call for each page. Disabling pagination has the AWS CLI only call once for the first page of command results. 

For example, if you run `aws s3api list-objects` on an Amazon S3 bucket that contains 3,500 objects, the AWS CLI only makes the first call to Amazon S3, returning only the first 1,000 objects in the final output.

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

### How to use the --page-size parameter
<a name="cli-usage-pagination-pagesize"></a>

If you see issues when running list commands on a large number of resources, the default page size might be too high. This can cause calls to AWS services to exceed the maximum allowed time and generate a "timed out" error. You can use the `--page-size` option to specify that the AWS CLI request a smaller number of items from each call to the AWS service. The AWS CLI still retrieves the full list, but performs a larger number of service API calls in the background and retrieves a smaller number of items with each call. This gives the individual calls a better chance of succeeding without a timeout. Changing the page size doesn't affect the output; it affects only the number of API calls that need to be made to generate the output.

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

### How to use the --max-items parameter
<a name="cli-usage-pagination-maxitems"></a>

To include fewer items at a time in the AWS CLI output, use the `--max-items` option. The AWS CLI still handles pagination with the service as described previously, but prints out only the number of items at a time that you specify.

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

### How to use the --starting-token parameter
<a name="cli-usage-pagination-startingtoken"></a>

If the number of items output (`--max-items`) is fewer than the total number of items returned by the underlying API calls, the output includes a `NextToken` that you can pass to a subsequent command to retrieve the next set of items. The following example shows how to use the `NextToken` value returned by the previous example, and enables you to retrieve the second 100 items.

**Note**  
The parameter `--starting-token` cannot be null or empty. If the previous command does not return a `NextToken` value, there are no more items to return and you do not need to call the command again.

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

The specified AWS service might not return items in the same order each time you call. If you specify different values for `--page-size` and `--max-items`, you can get unexpected results with missing or duplicated items. To prevent this, use the same number for `--page-size` and `--max-items` to sync the AWS CLI pagination with the pagination of the underlying service. You can also retrieve the whole list and perform any necessary paging operations locally.

## Client-side pager
<a name="cli-usage-pagination-clientside"></a>

AWS CLI version 2 provides the use of a client-side pager program for output. By default, this feature returns all output through your operating system’s default pager program. 

In order of precedence, you can specify the output pager in the following ways:
+ Using the `cli_pager` setting in the `config` file in the `default` or named profile.
+ Using the `AWS_PAGER` environment variable.
+ Using the `PAGER` environment variable.

In order of precedence, you can disable all use of an external paging program in the following ways:
+ Use the `--no-cli-pager` command line option to disable the pager for a single command use. 
+ Set the `cli_pager` setting or `AWS_PAGER` variable to an empty string.

**Topics**
+ [cli\$1pager](#cli-usage-pagination-clipager)
+ [AWS\$1PAGER](#cli-usage-pagination-awspager)
+ [--no-cli-pager](#cli-usage-pagination-noclipager)
+ [Pager flags](#cli-usage-pagination-flags)

### How to use the cli\$1pager setting
<a name="cli-usage-pagination-clipager"></a>

You can save your frequently used configuration settings and credentials in files that are maintained by the AWS CLI. Settings in a name profile take precedence over settings in the `default` profile. For more information on configuration settings, see [Configuration and credential file settings in the AWS CLI](cli-configure-files.md).

The following example sets the default output pager to the `less` program.

```
[default]
cli_pager=less
```

The following example sets the default to disable the use of a pager.

```
[default]
cli_pager=
```



### How to set the AWS\$1PAGER environment variable
<a name="cli-usage-pagination-awspager"></a>

The following example sets the default output pager to the `less` program. For more information on environment variables, see [Configuring environment variables for the AWS CLI](cli-configure-envvars.md).

------
#### [ Linux and macOS ]

```
$ export AWS_PAGER="less"
```

------
#### [ Windows ]

```
C:\> setx AWS_PAGER "less"
```

------

### How to use the --no-cli-pager option
<a name="cli-usage-pagination-noclipager"></a>

To disable the use of a pager on a single command, use the `--no-cli-pager` option. For more information on command line options, see [Command line options in the AWS CLI](cli-configure-options.md).

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

### How to use pager flags
<a name="cli-usage-pagination-flags"></a>

You can specify flags to use automatically with your paging program. Flags are dependent on the paging program you use. The below examples are for the typical defaults of `less` and `more`.

------
#### [ Linux and macOS ]

If you do not specify otherwise, the pager AWS CLI version 2 uses by default is `less`. If you don't have the `LESS` environment variable set, the AWS CLI version 2 uses the `FRX` flags. You can combine flags by specifying them when setting the AWS CLI pager.

The following example uses the `S` flag. This flag then combines with the default `FRX` flags to create a final `FRXS` flag.

```
$ export AWS_PAGER="less -S"
```

If you don't want any of the `FRX` flags, you can negate them. The following example negates the `F` flag to create a final `RX` flag.

```
$ export AWS_PAGER="less -+F"
```

For more information on `less` flags see [less](http://manpages.org/less/1#options) on *manpages.org*. 

------
#### [ Windows ]

If you do not specify otherwise, the pager AWS CLI version 2 uses by default is `more` with no additional flags.

The following example uses the `/c` parameter.

```
C:\> setx AWS_PAGER "more /c"
```

For more information on `more` flags, see `[more](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/more)` on *Microsoft Docs*.

------

# Filtering output in the AWS CLI
<a name="cli-usage-filter"></a>

The AWS Command Line Interface (AWS CLI) has both server-side and client-side filtering that you can use individually or together to filter your AWS CLI output. Server-side filtering is processed first and returns your output for client-side filtering. 
+ Server-side filtering is supported by the API, and you usually implement it with a `--filter` parameter. The service only returns matching results which can speed up HTTP response times for large data sets.
+ Client-side filtering is supported by the AWS CLI client using the `--query` parameter. This parameter has capabilities the server-side filtering might not have.

**Topics**
+ [Server-side filtering](#cli-usage-filter-server-side)
+ [Client-side filtering](#cli-usage-filter-client-side)
+ [Combining server-side and client-side filtering](#cli-usage-filter-combining)
+ [Additional resources](#cli-usage-filter-resources)

## Server-side filtering
<a name="cli-usage-filter-server-side"></a>

Server-side filtering in the AWS CLI is provided by the AWS service API. The AWS service only returns the records in the HTTP response that match your filter, which can speed up HTTP response times for large data sets. Since server-side filtering is defined by the service API, the parameter names and functions vary between services. Some common parameter names used for filtering are: 
+ `--filter` such as [ses](https://docs.aws.amazon.com/cli/latest/reference/ses/create-receipt-filter.html) and [ce](https://docs.aws.amazon.com/cli/latest/reference/ce/get-cost-and-usage.html). 
+ `--filters` such as [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), and [rds](https://docs.aws.amazon.com/cli/latest/reference/rds/describe-db-instances.html). 
+ Names starting with the word `filter`, for example `--filter-expression` for the [https://docs.aws.amazon.com/cli/latest/reference/dynamodb/scan.html](https://docs.aws.amazon.com/cli/latest/reference/dynamodb/scan.html) command.

For information about whether a specific command has server-side filtering and the filtering rules, see the [AWS CLI version 2 reference guide](https://docs.aws.amazon.com/cli/latest/reference/index.html).

## Client-side filtering
<a name="cli-usage-filter-client-side"></a>

The AWS CLI provides built-in JSON-based client-side filtering capabilities with the `--query` parameter. The `--query` parameter is a powerful tool you can use to customize the content and style of your output. The `--query` parameter takes the HTTP response that comes back from the server and filters the results before displaying them. Since the entire HTTP response is sent to the client before filtering, client-side filtering can be slower than server-side filtering for large data-sets.

Querying uses [JMESPath syntax](https://jmespath.org/) to create expressions for filtering your output. To learn JMESPath syntax, see [Tutorial](https://jmespath.org/tutorial.html) on the *JMESPath website*.

**Important**  
The output type you specify changes how the `--query` option operates:  
If you specify `--output text`, the output is paginated *before* the `--query` filter is applied, and the AWS CLI runs the query once on *each page* of the output. Due to this, the query includes the first matching element on each page which can result in unexpected extra output. To additionally filter the output, you can use other command line tools such as `head` or `tail`.
If you specify `--output json`, `--output yaml`, or `--output yaml-stream` the output is completely processed as a single, native structure before the `--query` filter is applied. The AWS CLI runs the query only once against the entire structure, producing a filtered result that is then output.

**Topics**
+ [Before you start](#cli-usage-filter-client-side-output)
+ [Identifiers](#cli-usage-filter-client-side-identifiers)
+ [Selecting from a list](#cli-usage-filter-client-side-select-list)
+ [Filtering nested data](#cli-usage-filter-client-side-nested)
+ [Flattening results](#cli-usage-filter-client-side-specific-flattening)
+ [Filtering for specific values](#cli-usage-filter-client-side-specific-values)
+ [Piping expressions](#cli-usage-filter-client-side-pipe)
+ [Filtering for multiple identifier values](#cli-usage-filter-client-side-miltiselect-list)
+ [Adding labels to identifier values](#cli-usage-filter-client-side-multiselect-hash)
+ [Functions](#cli-usage-filter-client-side-functions)
+ [Advanced `--query` examples](#cli-usage-filter-client-side-advanced)

### Before you start
<a name="cli-usage-filter-client-side-output"></a>

**Note**  
These filter expression examples are written for basic linux-like shells. When using these examples, be sure to use the correct quoting rules for your terminal shell. The way your terminal interprets your inputs can vastly change what is sent to the AWS CLI. How your terminal reads single quotes`'`, double quotes `"`, or backticks ``` can change how content is read.  
For more information, see [Using quotation marks and literals with strings in the AWS CLI](cli-usage-parameters-quoting-strings.md).

The following JSON output shows an example of what the `--query` parameter can produce. The output describes three Amazon EBS volumes attached to separate Amazon EC2 instances.

#### Example output
<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
    }
  ]
}
```

### Identifiers
<a name="cli-usage-filter-client-side-identifiers"></a>

Identifier are the labels for output values. When creating filters, you use identifiers to narrow down your query results. In the following output example, all identifiers such as `Volumes`, `AvailabilityZone`, and `AttachTime` are highlighted. 

```
$ 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
    }
  ]
}
```

For more information, see [Identifiers](https://jmespath.org/specification.html#identifiers ) on the *JMESPath website*.

### Selecting from a list
<a name="cli-usage-filter-client-side-select-list"></a>

A list or array is an identifier that is followed by a square bracket "`[`" such as `Volumes` and `Attachments` in the [Before you start](#cli-usage-filter-client-side-output). 

**Syntax**

```
<listName>[ ]
```

To filter through all output from an array, you can use the wildcard notation. [Wildcard](http://jmespath.org/specification.html#wildcard-expressions) expressions are expressions used to return elements using the `*` notation. 

The following example queries all `Volumes` content.

```
$ 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
  }
]
```

To view a specific volume in the array by index, you call the array index. For example, the first item in the `Volumes` array has an index of 0, resulting in the `Volumes[0]` query. For more information about array indexes, see [index expressions](http://jmespath.org/specification.html#index-expressions) on the *JMESPath website*.

```
$ 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
}
```

To view a specific range of volumes by index, use `slice` with the following syntax, where **start** is the starting array index, **stop** is the index where the filter stops processing, and **step** is the skip interval. 

**Syntax**

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

If any of these are omitted from the slice expression, they use the following default values:
+ Start – The first index in the list, 0.
+ Stop – The last index in the list.
+ Step – No step skipping, where the value is 1.

To return only the first two volumes, you use a start value of 0, a stop value of 2, and a step value of 1 as shown in the following example.

```
$ 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
  }
]
```

Since this example contains default values, you can shorten the slice from `Volumes[0:2:1]` to `Volumes[:2]`.

The following example omits default values and returns every two volumes in the entire array.

```
$ 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 can also use negative numbers to filter in the reverse order of an array as shown in the following example. 

```
$ 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
  }
]
```

For more information, see [Slices](https://jmespath.org/specification.html#slices) on the *JMESPath website*.

### Filtering nested data
<a name="cli-usage-filter-client-side-nested"></a>

To narrow the filtering of the `Volumes[*]` for nested values, you use subexpressions by appending a period and your filter criteria.

**Syntax**

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

The following example shows all `Attachments` information for all volumes.

```
$ 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"
    }
  ]
]
```

To filter further into the nested values, append the expression for each nested indentifier. The following example lists the `State` for all `Volumes`.

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

### Flattening results
<a name="cli-usage-filter-client-side-specific-flattening"></a>

For more information, see [SubExpressions](https://jmespath.org/specification.html#subexpressions) on the *JMESPath website*.

You can flatten the results for `Volumes[*].Attachments[*].State` by removing the wildcard notation resulting in the `Volumes[*].Attachments[].State` query. Flattening often is useful to improve the readablity of results.

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

For more information, see [Flatten](https://jmespath.org/specification.html#flatten) on the *JMESPath website*.

### Filtering for specific values
<a name="cli-usage-filter-client-side-specific-values"></a>

To filter for specific values in a list, you use a filter expression as shown in the following syntax.

**Syntax**

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

Expression comparators include `==`, `!=`, `<`, `<=`, `>`, and `>=` . The following example filters for the `VolumeIds` for all `Volumes` in an `Attached``State`.

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

This can then be flattened resulting in the following example.

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

The following example filters for the `VolumeIds` of all `Volumes` that have a size less than 20.

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

For more information, see [Filter Expressions](https://jmespath.org/specification.html#filterexpressions) on the *JMESPath website*.

### Piping expressions
<a name="cli-usage-filter-client-side-pipe"></a>

You can pipe results of a filter to a new list, and then filter the result with another expression using the following syntax: 

**Syntax**

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

The following example takes the filter results of the `Volumes[*].Attachments[].InstanceId` expression and outputs the first result in the array. 

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

This example does this by first creating the array from the following expression.

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

And then returns the first element in that array.

```
"i-a071c394"
```

For more information, see [Pipe Expressions](https://jmespath.org/specification.html#pipe-expressions) on the *JMESPath website*.

### Filtering for multiple identifier values
<a name="cli-usage-filter-client-side-miltiselect-list"></a>

To filter for multiple identifiers, you use a multiselect list by using the following syntax: 

**Syntax**

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

In the following example, `VolumeId` and `VolumeType` are filtered in the `Volumes` list resulting in the following expression.

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

To add nested data to the list, you add another multiselect list. The following example expands on the previous example by also filtering for `InstanceId` and `State` in the nested `Attachments` list. This results in the following expression.

```
$ 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"
      ]
    ]
  ]
]
```

To be more readable, flatten out the expression as shown in the following example.

```
$ 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"
  ]
]
```

For more information, see [Multiselect list](https://jmespath.org/specification.html#multiselectlist) on the *JMESPath website*.

### Adding labels to identifier values
<a name="cli-usage-filter-client-side-multiselect-hash"></a>

To make this output easier to read, use a multiselect hash with the following syntax.

**Syntax**

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

Your identifier label does not need to be the same as the name of the identifier. The following example uses the label `VolumeType` for the `VolumeType` values.

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

For simplicity, the following example keeps the identifier names for each label and displays the `VolumeId`, `VolumeType`, `InstanceId`, and `State` for all volumes:

```
$ 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"
  }
]
```

For more information, see [Multiselect hash](https://jmespath.org/specification.html#multiselecthash) on the *JMESPath website*.

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

The JMESPath syntax contains many functions that you can use for your queries. For information on JMESPath functions, see [Built-in Functions](https://jmespath.org/specification.html#built-in-functions) on the *JMESPath website*.

To demonstrate how you can incorporate a function into your queries, the following example uses the `sort_by` function. The `sort_by` function sorts an array using an expression as the sort key using the following syntax:

**Syntax**

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

The following example uses the previous [multiselect hash example](#cli-usage-filter-client-side-multiselect-hash) and sorts the output by `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"
  }
]
```

For more information, see [sort\$1by](https://jmespath.org/specification.html#sort-by) on the *JMESPath website*.

### Advanced `--query` examples
<a name="cli-usage-filter-client-side-advanced"></a>

**To extract information from a specific item**

The following example uses the `--query` parameter to find a specific item in a list and then extracts information from that item. The example lists all of the `AvailabilityZones` associated with the specified service endpoint. It extracts the item from the `ServiceDetails` list that has the specified `ServiceName`, then outputs the `AvailabilityZones` field from that selected item. 

```
$ 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"
    ]
]
```

**To show snapshots after the specified creation date**

The following example shows how to list all of your snapshots that were created after a specified date, including only a few of the available fields in the output.

```
$ 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
    }
]
```

**To show the most recent AMIs**

The following example lists the five most recent Amazon Machine Images (AMIs) that you created, sorted from most recent to oldest.

```
$ 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"
    }
]
```

**To show unhealthy Auto Scaling instances**

The following example shows only the `InstanceId` for any unhealthy instances in the specified Auto Scaling group.

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

**To include volumes with the specified tag**

The following example describes all instances with a `test` tag. As long as there is another tag beside `test` attached to the volume, the volume is still returned in the results.

The below expression to return all tags with the `test` tag in an array. Any tags that are not the `test` tag contain a `null` value.

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

**To exclude volumes with the specified tag**

The following example describes all instances without a `test` tag. Using a simple `?Value != `test`` expression does not work for excluding a volume as volumes can have multiple tags. As long as there is another tag beside `test` attached to the volume, the volume is still returned in the results.

To exclude all volumes with the `test` tag, start with the below expression to return all tags with the `test` tag in an array. Any tags that are not the `test` tag contain a `null` value.

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

Then filter out all the positive `test` results using the `not_null` function. 

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

Pipe the results to flatten out the results resulting in the following query.

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

## Combining server-side and client-side filtering
<a name="cli-usage-filter-combining"></a>

You can use server-side and client-side filtering together. Server-side filtering is completed first, which sends the data to the client that the `--query` parameter then filters. If you're using large data sets, using server-side filtering first can lower the amount of data sent to the client for each AWS CLI call, while still keeping the powerful customization that client-side filtering provides.

The following example lists Amazon EC2 volumes using both server-side and client-side filtering. The service filters a list of all attached volumes in the `us-west-2a` Availability Zone. The `--query` parameter further limits the output to only those volumes with a `Size` value that is larger than 50, and shows only the specified fields with user-defined names.

```
$ 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"
    }
]
```

The following example retrieves a list of images that meet several criteria. It then uses the `--query` parameter to sort the output by `CreationDate`, selecting only the most recent. Finally, it displays the `ImageId` of that one image.

```
$ 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
```

The following example displays the number of available volumes that are more than 1000 IOPS by using `length` to count how many are in a list.

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

The following example retrieves the names of Auto Scaling groups that are using launch configurations in the specified AWS Region that are using CloudFormation stacks.

```
$ 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"
]
```

## Additional resources
<a name="cli-usage-filter-resources"></a>

**AWS CLI autoprompt**  
When beginning to use filter expressions, you can use the auto-prompt feature in the AWS CLI version 2. The auto-prompt feature provides a preview when you press the **F5** key. For more information, see [Enabling and using command prompts in the AWS CLI](cli-usage-parameters-prompting.md).

**JMESPath Terminal**  
JMESPath Terminal is an interactive terminal command to experiment with JMESPath expressions that are used for client-side filtering. Using the `jpterm` command, the terminal shows immediate query results as you're typing. You can directly pipe AWS CLI output to the terminal, enabling advanced querying experimentation.   
The following example pipes `aws ec2 describe-volumes` output directly to JMESPath Terminal.  

```
$ aws ec2 describe-volumes | jpterm
```
For more information on JMESPath Terminal and installation instructions, see [JMESPath Terminal](https://github.com/jmespath/jmespath.terminal) on *GitHub*.

**jq utility**  
The `jq` utility provides you a way to transform your output on the client-side to an output format you desire. For more information on `jq` and installation instructions, see [jq](https://stedolan.github.io/jq/) on *GitHub*.