10

I am parsing an API which sends me a JSON response like this:

{
  "newList": {
    "243": {
      "id": "243",
      "name": "test",
      "create": {
        "date": "2017-08-31 13:57:29"
      }
    },
    "244": {
      "id": "244",
      "name": "test",
      "create": {
        "date": "2017-08-31 13:57:29"
      }
    }
 }
}

I am trying to get the name and the create date out of this using bash with jq, so for with little to no success.

jq '.newList' does work and brings me down one level, but that's not sufficient.

jq '.newList .243' gives me a compile error. Furthermore, the 243 is dynamic and can change at any time. What am I doing wrong here?

SnIpY
  • 642
  • 9
  • 27

1 Answers1

16

Assuming your root node name is newList as you have in the question given, to get the id and created date, you can do string interpolation with jq

api-producing-json | jq --raw-output '.newList[] | "\(.id) \(.create.date)"'

This way the filter is independent of the dynamic numbers in the nodes (243, 244). Drop the --raw-output flag if you need the output with quotes.

To process further in a loop, you can iterate it over a bash loop,

while read -r id name date; do
    echo "Do whatever with ${id} ${name} ${date}"
done< <(api-producing-json | jq --raw-output '.newList[] | "\(.id) \(.name) \(.create.date)"')

or to even more carefully delimit the words if you are worried about the spaces in any of the fields, use a delimiter as | in the filter as "\(.id)|\(.name)|\(.create.date)" and use the read command in the while loop by setting IFS=| so the variables are stored appropriately.


Always use the official jq - documentation for help and use this nice playground to test out the filters, jq - online

Inian
  • 71,145
  • 9
  • 121
  • 139
  • How to adapt the code at loop where `api-producing-json` is `stdin` from Chrome Native Messaging? See [How to parse JSON from stdin at Native Messaging host?](https://stackoverflow.com/questions/48385086/how-to-parse-json-from-stdin-at-native-messaging-host) – guest271314 Jan 23 '18 at 22:17
  • How would this look if I wanted to include the equivalent of the "243" and "244" that appear as field names rather than as value of the "id": fields? (Because my input does not have that redundancy.) – Randall Schulz Apr 02 '19 at 19:54