2

I'm requesting a JSON from Twitch with: curl --silent -H 'Accept: application/vnd.twitchtv.v3+json' -X GET https://api.twitch.tv/kraken/streams/$1 where $1 is the input I send for my function.

Now what I'm aiming for is to filter the JSON by piping this after the curl: | jq '.stream.channel.something' I am trying to get 3 different string values through jq filtering I can manage to get them to this level:

{
    "first": "lor"
    "second": "em"
    "third": "ipsum"
}

Way to operate with them inside the code?


Alternatives I've come up with are:

  1. Create output of the curl, filter it and then delete.
  2. Send 3 cURL requests -- (Useless performance hog?).
  • I'm not jq-enabled, so could you simplify your question? Are you saying that you have that curly-bracket-first-second-third string as output from jq? And you want to "operate" what with it? – Jeff Schaller Feb 12 '16 at 17:31
  • Yes, after filtering it with jq, I'd like to use those three strings in my script to output them separately in my printf/echo command. echo "First value: ${first}" etc. – confusedoverflow Feb 13 '16 at 14:16
  • Does jq have the ability to extract the "first" &etc values natively, or is that as far as jq goes? Thinking of saving the curl output to a temporary variable then calling jq to extract each. – Jeff Schaller Feb 13 '16 at 15:33
2

As I said, I don't know much about json or jq, but I wasn't able to get jq to parse your sample output of:

{
    "first": "lor"
    "second": "em"
    "third": "ipsum"
}

parse error: Expected separator between values at line 3, column 12

So I turned the input into:

{
  "stream" : {
    "channel" : {
      "something" : {
        "first": "lor",
        "second": "em",
        "third": "ipsum"
      }
    }
  }
}

... based on what I gathered from your call to jq. Hopefully that's similar to what the curl command is outputting.

If it is, then it seems like this sequence gets you what you want:

# this is just your original curl command, wrapped in command substitution,
# in order to assign it to a variable named 'output':
output=$(curl --silent -H 'Accept: application/vnd.twitchtv.v3+json' -X GET https://api.twitch.tv/kraken/streams/$1)

# these three lines take the output stream from above and pipe it to
# separate jq calls to extract the values; I added some pretty-printing whitespace
first=$( echo "$output" | jq '.["stream"]["channel"]["something"]["first"]' )
second=$(echo "$output" | jq '.["stream"]["channel"]["something"]["second"]')
third=$( echo "$output" | jq '.["stream"]["channel"]["something"]["third"]' )

With the results:

$ echo $first
"lor"
$ echo $second
"em"
$ echo $third
"ipsum"
  • 1
    apparently you can add the -r flag to jq to have it print the raw data (lor) instead of the JSON text ("lor"), if that's preferable. – Jeff Schaller Feb 19 '16 at 2:49
  • 1
    Avoid .stream.channel.something.first format with jq, it's unreliable. it's better to use '.["stream"]["channel"]["something"]["first"]' It's guaranteed to work no matter if the keys include dots or hyphens and can save hours of pain. The OP example is missing comma separators. – ColinSeligSmith Apr 5 '16 at 15:38
  • I'll take your word for it, @css1971! I've updated answer with the new syntax -- no need for hours of pain! – Jeff Schaller Apr 5 '16 at 17:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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