JMESPath queries let AWS CLI return only the fields, objects, and counts that matter instead of a full service response. That makes interactive checks shorter and gives scripts a smaller, predictable result to pass into the next step.

The --query option applies a JMESPath expression after AWS CLI receives the response body. Projections such as list[].field pull values from every item, multiselect hashes build smaller labeled objects, filters keep only matching items, and functions such as length() reshape the final result before --output renders it.

The examples below use Linux and macOS shell quoting, where the whole expression normally stays inside single quotes and string literals inside filters use backticks. Current AWS CLI v2 documentation also warns that --output text on paginated commands applies the query once per page, so build expressions with json, yaml, or yaml-stream first and switch to text only after the query already returns the exact scalar or column order required.

Steps to use JMESPath queries in AWS CLI:

  1. Inspect the response shape before writing the query.
    $ aws ec2 describe-regions --generate-cli-skeleton output
    {
        "Regions": [
            {
                "OptInStatus": "OptInStatus",
                "Geography": [
                    {
                        "Name": "Name"
                    }
                ],
                "RegionName": "RegionName",
                "Endpoint": "Endpoint"
            }
        ]
    }

    --generate-cli-skeleton output renders a local sample response without calling an AWS API, but the generated skeleton is not stable across CLI versions.

  2. Project one field from each list item when only the identifier list matters.
    $ aws ec2 describe-regions --generate-cli-skeleton output --query 'Regions[].RegionName' --output json
    [
        "RegionName"
    ]

    The list[].field pattern is the fastest way to turn a list of large objects into a simple list of names, IDs, or ARNs.

  3. Build a smaller labeled object when several fields must stay together in the result.
    $ aws ec2 describe-regions --generate-cli-skeleton output --query 'Regions[].{Region:RegionName,Endpoint:Endpoint}' --output json
    [
        {
            "Region": "RegionName",
            "Endpoint": "Endpoint"
        }
    ]

    A multiselect hash such as {Region:RegionName,Endpoint:Endpoint} keeps only the chosen fields and renames them into keys that are easier to read and reuse.

  4. Filter matching items after any server-side prefilter when only a subset of the response should remain.
    $ aws ec2 describe-volumes --filters "Name=status,Values=available" --query 'Volumes[?Iops > `1000`].{Id:VolumeId,Size:Size,Type:VolumeType}' --output json
    [
        {
            "Id": "vol-0be9bb0bf12345678",
            "Size": 80,
            "Type": "gp3"
        }
    ]

    --filters runs on the service side first, and the [? ... ] expression then filters the returned JSON locally. Use backticks around literal values inside the filter, such as `1000` or `gp3`, and expect the final values to reflect the current account inventory.

  5. Pipe one intermediate result into a second expression when the first projection still needs one final selection.
    $ aws ec2 describe-regions --generate-cli-skeleton output --query 'Regions[].RegionName | [0]' --output text
    RegionName

    The pipe operator | hands the first result to the next expression, which is useful when you need to take one item, slice a list, or apply a final shape after filtering.

  6. Count matching items with length() when the total matters more than the full list.
    $ aws ec2 describe-volumes --filters "Name=status,Values=available" --query 'length(Volumes[?Iops > `1000`])' --output json
    3

    length() returns a number instead of a JSON array, which is useful for quick capacity checks, guard conditions, and script decisions. The count changes with the matching resources in the current account and region.

  7. Sort the result with sort_by() before you print it when the list needs a stable order.
    $ aws ec2 describe-volumes --generate-cli-skeleton output --query 'sort_by(Volumes, &VolumeId)[].{Id:VolumeId,Size:Size,Type:VolumeType}' --output json
    [
        {
            "Id": "VolumeId",
            "Size": 0,
            "Type": "VolumeType"
        }
    ]

    The &VolumeId expression tells sort_by() which field to compare. On a live multi-volume response, the same pattern gives you a predictable order before any follow-up selection.

  8. Switch to --output text only after the query already returns the exact scalar or field order needed by the next shell step.
    $ aws s3api list-buckets --generate-cli-skeleton output --query 'Buckets[0].Name' --output text
    Name

    Current AWS CLI documentation says paginated commands apply --query once per page when --output text is used, so build and test the expression with json, yaml, or yaml-stream first.