How to get jq to print valid json after applying a filter

Viewed 882

I'm working on jq filtering and output of results to output into another program that accepts a JSON payload. Consider the following example:

INPUT:

My-MBP:myorg myname$ aws ec2 describe-snapshots --owner-id 12345678 | jq '.Snapshots[] | select(.Description | contains("myorg-database-b"))'

RESULT:

{
  "Description": "myorg-database-b redacted",
  "Encrypted": false,
  "VolumeId": "vol-1234",
  "State": "completed",
  "VolumeSize": 500,
  "StartTime": "2018-08-28T17:52:14.000Z",
  "Progress": "100%",
  "OwnerId": "12345678",
  "SnapshotId": "snap-2424"
}
{
  "Description": "myorg-database-b redacted",
  "Encrypted": false,
  "VolumeId": "vol-23456",
  "State": "completed",
  "VolumeSize": 500,
  "StartTime": "2018-08-28T19:01:18.000Z",
  "Progress": "100%",
  "OwnerId": "12345678",
  "SnapshotId": "snap-5535"
}

No matter what I try to do, I can't get jq to print valid JSON so that I can pipe it into another program.

The original JSON from AWS was an array of objects, why can't I get back a valid array of objects? Am I doing something wrong here?

Here is what the AWS payload looks like before it gets piped into jq:

{
    "Snapshots": [
        {
            "Description": "myorg-database-b redacted",
            "Encrypted": false,
            "VolumeId": "vol-23456",
            "State": "completed",
            "VolumeSize": 500,
            "StartTime": "2018-08-28T19:01:18.000Z",
            "Progress": "100%",
            "OwnerId": "12345678",
            "SnapshotId": "snap-5535"
        }, 
        {
            "Description": "myorg-database-b redacted",
            "Encrypted": false,
            "VolumeId": "vol-23456",
            "State": "completed",
            "VolumeSize": 500,
            "StartTime": "2018-08-28T19:01:18.000Z",
            "Progress": "100%",
            "OwnerId": "12345678",
            "SnapshotId": "snap-5535"
        }
    ]
}

Any help would be appreciated.

1 Answers

You can wrap the entire jq expression into square brackets to make it collect the filter output into an array (documented in Array construction section):

'[ .Snapshots[] | select(.Description | contains("myorg-database-b")) ]'

results in:

[
  {
    "Description": "myorg-database-b redacted",
    "Encrypted": false,
    "VolumeId": "vol-23456",
    "State": "completed",
    "VolumeSize": 500,
    "StartTime": "2018-08-28T19:01:18.000Z",
    "Progress": "100%",
    "OwnerId": "12345678",
    "SnapshotId": "snap-5535"
  },
  {
    "Description": "myorg-database-b redacted",
    "Encrypted": false,
    "VolumeId": "vol-23456",
    "State": "completed",
    "VolumeSize": 500,
    "StartTime": "2018-08-28T19:01:18.000Z",
    "Progress": "100%",
    "OwnerId": "12345678",
    "SnapshotId": "snap-5535"
  }
]
Related