Search code examples
jsonbashamazon-web-servicesaws-clijmespath

Can you print the values of a JSON array in an AWS, using a JMESPath query?


I am trying to list all the SQS queues in our account using aws sqs list-queues into a bash one-item-per-line output.

Problem is it comes through as a JSON object

{
  "QueueUrls": [
    "url",
    "url",
    "etc..."
  ]
}

I can use JMESpath to get this aws sqs list-queues --query 'QueueUrls[]'

but that gives me:

[
   "url",
   "url",
   "etc..."
]

Question

Is it possible to print the output from a JSON array, using a JMESPath query in a one-per-line style?

From:

{
  "key": [
    "string",
    "string",
    "string"
  ]
}

To:

string
string
string

What I want

I want:

url
url
url

What I've tried

  • Using aws sqs list-queues --query 'QueueUrls[]' --output text

    I get the urls all in one line:

    url   url   url   etc...
    
  • I've also looked at this other question but nothing I tried to put into the query gave me the flat-output

Work around

Currently I'm doing aws sqs list-queues --output text | sed -E 's/^.+\s+(.+)$/\1/' to extract the url line from the text output.

(Definitely also posible with awk but the sed regex was the thing my mind did first)

Why I want it

I want to use the output in a bash script I'm writing. I want to grep the lines and do some other processing on the output.

In this case it was simple to do the --output text trick but for more complicated AWS objects I'd like to know if it is possible using JMESPath.


Solution

  • You can achieve this by joining the elements of the JSON array with the join bulletin function.

    You have two possible and equivalent syntaxes:

    1. Chaining the function on the array, and using the current node — @
      QueueUrls.join(`\n`, @)
      
    2. Wrapping the whole array in the function
      join(`\n`, QueueUrls)
      

    Note: backticks — `, in JMESPath is the delimiter for a literal expression.


    So, your AWS command ends up being:

    aws sqs list-queues --query 'QueueUrls.join(`\n`, @)' --output text