
Estou solicitando um JSON do Twitch com:
curl --silent -H 'Accept: application/vnd.twitchtv.v3+json' -X GET https://api.twitch.tv/kraken/streams/$1
onde $1
está a entrada que envio para minha função.
Agora, o que pretendo é filtrar o JSON canalizando-o após o curl: | jq '.stream.channel.something'
estou tentando obter três valores de string diferentes por meio da filtragem jq e consigo levá-los a este nível:
{
"first": "lor"
"second": "em"
"third": "ipsum"
}
Maneira de operar com eles dentro do código?
As alternativas que encontrei são:
- Crie a saída do curl, filtre-a e exclua.
- Envie 3 solicitações cURL - (desempenho inútil?).
Responder1
Como eu disse, não sei muito sobre json ou jq, mas não consegui fazer com que jq analisasse seu exemplo de saída de:
{
"first": "lor"
"second": "em"
"third": "ipsum"
}
parse error: Expected separator between values at line 3, column 12
Então transformei a entrada em:
{
"stream" : {
"channel" : {
"something" : {
"first": "lor",
"second": "em",
"third": "ipsum"
}
}
}
}
... com base no que descobri em sua ligação para jq. Esperançosamente, isso é semelhante ao que o comando curl está gerando.
Se for, então parece que esta sequência dá o que você deseja:
# 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"]' )
Com os resultados:
$ echo $first
"lor"
$ echo $second
"em"
$ echo $third
"ipsum"
Responder2
Supondo que seu arquivo seja JSON válido (o que os dados da pergunta não são):
{
"first": "lor",
"second": "em",
"third": "ipsum"
}
Você pode usar jq
isso para criar três atribuições, que podem ser avaliadas com segurança no shell:
eval "$(
jq -r '
@sh "first=\(.first)",
@sh "second=\(.second)",
@sh "third=\(.third)"' file.json
)"
O @sh
operador in jq
produzirá atribuições no formulário first='lor'
para avaliação do shell.
Para o bash
shell, você também pode criar uma atribuição de array:
eval "$(
jq -r '@sh "array=(\([.first, .second, .third]))"' file.json
)"
Aqui, o jq
comando geraria algo como array=('lor' 'em' 'ipsum')
, que quando avaliado por bash
criaria o array chamado array
com o conteúdo fornecido.
Você poderia usar a jq
instrução @sh "array=(\([.[]]))"
para criar uma matriz de valores de todas as chaves, assumindo que cada valor é um escalar.