Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a JSON output that contains a list of objects stored in a variable. (I may not be phrasing that right)

[
  {
    "item1": "value1",
    "item2": "value2",
    "sub items": [
      {
        "subitem": "subvalue"
      }
    ]
  },
  {
    "item1": "value1_2",
    "item2": "value2_2",
    "sub items_2": [
      {
        "subitem_2": "subvalue_2"
      }
    ]
  }
]

I need all the values for item2 in a array for a bash script to be run on ubuntu 14.04.1.

I have found a bunch of ways to get the entire result into an array but not just the items I need

share|improve this question
up vote 6 down vote accepted

Using :

$ cat json
[
  {
    "item1": "value1",
    "item2": "value2",
    "sub items": [
      {
        "subitem": "subvalue"
      }
    ]
  },
  {
    "item1": "value1_2",
    "item2": "value2_2",
    "sub items_2": [
      {
        "subitem_2": "subvalue_2"
      }
    ]
  }
]

CODE:

arr=( $(jq -r '.[].item2' json) )
printf '%s\n' "${arr[@]}"

OUTPUT:

value2
value2_2
share|improve this answer
    
Is it possible to do this from a variable instead of a file? I try to avoid excess filesystem access if I don't need it. Once I pull this array I am done with the json output. – JpaytonWPD Jan 7 '15 at 0:10
    
Have you tried something ? – Gilles Quenot Jan 7 '15 at 0:13
1  
jq . <<< "$json" it's shell (bash) related, non specific to jq – Gilles Quenot Jan 7 '15 at 0:23
1  
Missing parentheses : arr=( $(...) ) – Gilles Quenot Jan 7 '15 at 0:35
1  
Great jq command, but please don't parse command output into an array with arr=( $(...) ) (even though it happens to work with the sample input): it doesn't work as intended with embedded or leading/trailing whitespace and can result in accidental globbing. – mklement0 Jul 14 at 5:21

Thanks to sputnick I got to this:

arr=( $(curl -k https://localhost/api | jq -r '.[].item2') )

The JSON I have is the output from an API. All I needed to do wans remove the file argument and pipe | the output of curl to jq. Works great and saved some steps.

share|improve this answer
    
That code's actually a bit buggy. Look at what happens if you have a result element of * -- it'll get replaced with a list of files in your current directory. – Charles Duffy Oct 5 at 2:55
    
Similarly, an item2 value with whitespace in it would become more than one array element. – Charles Duffy Oct 5 at 3:02

The following is actually buggy:

# BAD: Output line of * is replaced with list of local files; can't deal with whitespace
arr=$( curl -k "$url" | jq -r '.[].item2' )

Instead, use:

# GOOD (with bash 4.x+), but can't detect failure
readarray -t arr < <(curl -k "$url" | jq -r '.[].item2' )

...or, even better...

# GOOD (with bash 3.x+), *and* has nonzero status if curl or jq fails
IFS=$'\n' read -r -d '' -a arr \
  < <(set -o pipefail; curl --fail -k "$url" | jq -r '.[].item2' && printf '\0')
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.