Reputation: 69
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
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
Reputation: 531948
You need to pipe the output of .[]
into the next filter.
jq -r '.[] | .success.username' tmp.json
Upvotes: 3