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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.