1

I am doing something fundamentally wrong but just can't see what, could some kind person point out my fault with jq or JSON here?

I have the the following child objects contained within an array “entries

{
    "profile": {
        "name": "TesterRun1",
        "download": {
            "entries": [{
                    "ENTRY_A": "testserver1_place_com",
                    "store": "A",
                    "type": "direct"
                },
                {
                    "ENTRY_B": "testserver2_anotherplace_com",
                    "store": "B",
                    "type": "bypass"
                },
                {
                    "ENTRY_B": "testserver2_anotherplace_com",
                    "store": "A",
                    "type": "bypass"
                }
            ]
        }
    }
}

I wish to convert these to an array accessible by bash via the jq function “to_entries” using the below query but so far nothing!

jq 'to_entries|.[]|.profile.download.entries|select(.store=="A")|.[]'

You can see here that nothing is returned on JQ Play - enter link description here

Please help save my sanity, what am I doing wrong

2
  • to_entries does not make things accessible to bash. Not sure where you got the idea that's what it does. Commented Sep 14, 2017 at 22:27
  • Beyond that, what's the actual output you want? Commented Sep 14, 2017 at 22:28

2 Answers 2

1

to_entries has nothing whatsoever to do with exposing JQ results to bash. Rather, it takes each entry in a JSON object and emits a {"key": key, "value": value} pair.

That can be useful, if you want to identify and extract arbitrary keys. For example:

#!/usr/bin/env bash

jq_script='
.profile.download.entries[]
| select(.store == "A")
| to_entries[]
| select(.key != "store")
| select(.key != "type")
| [.key, .value]
| @tsv
'

declare -A array=( )
while IFS=$'\t' read -r key value; do
  array[$key]=$value
done < <(jq -r "$jq_script")

# print array output
declare -p array

...will, when given your input on stdin, emit (albeit on a single line, without the whitespace changes):

declare -A array=([ENTRY_A]="testserver1_place_com"
                  [ENTRY_B]="testserver2_anotherplace_com" )

...which I assume, for lack of any better description in the question, is what you actually want.

Sign up to request clarification or add additional context in comments.

1 Comment

Hi Charles, apologies for not giving an example of desired output. I think from what you have show is the records I was looking to extract do not require to be placed into a separate object prior to looping through with bash. Seems much clearer after a nights sleep and with such a clear example of handing the data straight to an array. This is exactly what I need, thanks you for your very fast and clear response.
0

Here is a slightly different approach (with some cleaned-up data) which captures the output from jq into separate column arrays.

#!/bin/bash
data='{
  "profile": {
    "name": "TesterRun1",
    "download": {
      "entries": [
        {
          "entry": "testserver1_place_com",
          "store": "A",
          "type": "direct"
        },
        {
          "entry": "testserver2_anotherplace_com",
          "store": "B",
          "type": "bypass"
        },
        {
          "entry": "testserver2_anotherplace_com",
          "store": "A",
          "type": "bypass"
        }
      ]
    }
  }
}'
filter='
        .profile.download.entries[]
      | select(.store == "A")
      | .entry, .store, .type
'      
declare -a ENTRY
declare -a STORE
declare -a TYPE
i=0
while read -r entry; read -r store; read -r type; do
    ENTRY[$i]="$entry"
    STORE[$i]="$store"
    TYPE[$i]="$type"
    i=$((i + 1))
done < <(jq -Mr "$filter" <<< "$data")
declare -p ENTRY STORE TYPE

Output

declare -a ENTRY='([0]="testserver1_place_com" [1]="testserver2_anotherplace_com")'
declare -a STORE='([0]="A" [1]="A")'
declare -a TYPE='([0]="direct" [1]="bypass")'

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.