
Я запрашиваю JSON из Twitch со следующими данными:
curl --silent -H 'Accept: application/vnd.twitchtv.v3+json' -X GET https://api.twitch.tv/kraken/streams/$1
где $1
находятся входные данные, которые я отправляю для своей функции.
Теперь моя цель — отфильтровать JSON, передав это после curl: | jq '.stream.channel.something'
Я пытаюсь получить 3 разных строковых значения с помощью фильтрации jq. Мне удается довести их до этого уровня:
{
"first": "lor"
"second": "em"
"third": "ipsum"
}
Как с ними работать внутри кода?
Альтернативы, которые я придумал, следующие:
- Создайте вывод curl, отфильтруйте его, а затем удалите.
- Отправьте 3 запроса cURL -- (бесполезный пожиратель производительности?).
решение1
Как я уже сказал, я не очень разбираюсь в json или jq, но мне не удалось заставить jq проанализировать ваш пример вывода:
{
"first": "lor"
"second": "em"
"third": "ipsum"
}
parse error: Expected separator between values at line 3, column 12
Поэтому я превратил входные данные в:
{
"stream" : {
"channel" : {
"something" : {
"first": "lor",
"second": "em",
"third": "ipsum"
}
}
}
}
... на основе того, что я понял из вашего вызова jq. Надеюсь, это похоже на то, что выводит команда curl.
Если это так, то, похоже, эта последовательность даст вам то, что вы хотите:
# 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"]' )
С результатами:
$ echo $first
"lor"
$ echo $second
"em"
$ echo $third
"ipsum"
решение2
Предположим, что ваш файл является допустимым JSON (а данные в вопросе таковыми не являются):
{
"first": "lor",
"second": "em",
"third": "ipsum"
}
Вы можете использовать jq
это для создания трех присваиваний, которые можно безопасно оценить в оболочке:
eval "$(
jq -r '
@sh "first=\(.first)",
@sh "second=\(.second)",
@sh "third=\(.third)"' file.json
)"
Оператор @sh
in jq
выведет назначения на форму first='lor'
, которую оболочка сможет оценить.
Для bash
оболочки вы также можете создать массив назначений:
eval "$(
jq -r '@sh "array=(\([.first, .second, .third]))"' file.json
)"
Здесь jq
команда сгенерирует что-то вроде array=('lor' 'em' 'ipsum')
, что при вычислении bash
создаст массив array
с указанным содержимым.
Вы можете использовать этот jq
оператор @sh "array=(\([.[]]))"
для создания массива значений всех ключей, предполагая, что каждое значение является скаляром.