
Estoy solicitando un JSON de Twitch con:
curl --silent -H 'Accept: application/vnd.twitchtv.v3+json' -X GET https://api.twitch.tv/kraken/streams/$1
donde $1
está el input que envío para mi función.
Ahora lo que pretendo es filtrar el JSON canalizando esto después del curl: | jq '.stream.channel.something'
estoy tratando de obtener 3 valores de cadena diferentes a través del filtrado jq. Puedo lograr llevarlos a este nivel:
{
"first": "lor"
"second": "em"
"third": "ipsum"
}
¿Manera de operar con ellos dentro del código?
Las alternativas que se me han ocurrido son:
- Cree la salida del rizo, fíltrelo y luego elimínelo.
- Envíe 3 solicitudes cURL - (¿Acaparador de rendimiento inútil?).
Respuesta1
Como dije, no sé mucho sobre json o jq, pero no pude lograr que jq analizara el resultado de muestra de:
{
"first": "lor"
"second": "em"
"third": "ipsum"
}
parse error: Expected separator between values at line 3, column 12
Entonces convertí la entrada en:
{
"stream" : {
"channel" : {
"something" : {
"first": "lor",
"second": "em",
"third": "ipsum"
}
}
}
}
... basado en lo que deduje de tu llamada a jq. Con suerte, eso es similar a lo que genera el comando curl.
Si es así, entonces parece que esta secuencia te proporciona lo que deseas:
# 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"]' )
Con los resultados:
$ echo $first
"lor"
$ echo $second
"em"
$ echo $third
"ipsum"
Respuesta2
Suponiendo que su archivo es JSON válido (que los datos de la pregunta no lo son):
{
"first": "lor",
"second": "em",
"third": "ipsum"
}
Puede utilizar jq
para crear tres asignaciones a partir de esto, que puede evaluar de forma segura en el shell:
eval "$(
jq -r '
@sh "first=\(.first)",
@sh "second=\(.second)",
@sh "third=\(.third)"' file.json
)"
El @sh
operador en jq
generará asignaciones en el formulario first='lor'
para que el shell las evalúe.
Para el bash
shell, también puedes crear una asignación de matriz:
eval "$(
jq -r '@sh "array=(\([.first, .second, .third]))"' file.json
)"
Aquí, el jq
comando generaría algo como array=('lor' 'em' 'ipsum')
, que cuando se evaluara bash
crearía la matriz llamada array
con el contenido dado.
Podría usar la jq
declaración @sh "array=(\([.[]]))"
para crear una matriz de los valores de todas las claves, asumiendo que cada valor es un escalar.