Pirate Dan
Pirate Dan

Reputation: 69

I cannot get jq to give me the value I'm looking for.

I'm trying to use jq to get a value from the JSON that cURL returns.

This is the JSON cURL passes to jq (and, FTR, I want jq to return "VALUE-I-WANT" without the quotation marks):

[  
   {  
      "success":{  
         "username":"VALUE-I-WANT"
      }
   }
]

I initially tried this:

jq ' . | .success | .username'

and got

jq: error (at <stdin>:0): Cannot index array with string "success"

I then tried a bunch of variations, with no luck.

With a bunch of searching the web, I found this SE entry, and thought it might have been my saviour (spoiler, it wasn't). But it led me to try these:

jq -r '.[].success.username'
jq -r '.[].success'

They didn't return an error, they returned "null". Which may or may not be an improvement.

Can anybody tell me what I'm doing wrong here? And why it's wrong?

Upvotes: 2

Views: 1482

Answers (2)

mklement0
mklement0

Reputation: 439477

tl;dr

# Extract .success.username from ALL array elements.
# .[] enumerates all array elements
# -r produces raw (unquoted) output
jq -r '.[].success.username' file.json

# Extract .success.username only from the 1st array element.
jq -r '.[0].success.username' file.json

Your input is an array, so in order to access its elements you need .[], the array/object-value iterator (as the name suggests, it can also enumerate the properties of an object):

Just . | sends the input (.) array as a whole through the pipeline, and an array only has numerical indices, so the attempt to index (access) it with .success.username fails.

Thus, simply replacing . | with .[] | in your original attempt, combined with -r to get raw (unquoted output), should solve your problem, as shown in chepner's helpful answer.

However, peak points out that since at least jq 1.3 (current as of this writing is jq 1.5) you don't strictly need a pipeline, as demonstrated in the commands at the top.
So the 2nd command in your question should work with your sample input, unless you're using an older version.

Upvotes: 3

chepner
chepner

Reputation: 531948

You need to pipe the output of .[] into the next filter.

jq -r '.[] | .success.username' tmp.json

Upvotes: 3

Related Questions