Я не могу использовать ни один из ответов здесь. Нет доступных jq, нет массивов оболочек, нет объявлений, нет grep -P, нет look -hind и lookahead, нет Python, нет Perl, нет Ruby, нет - даже нет Bash ... Остальные ответы просто не работают хорошо. JavaScript звучит знакомо, но в банке написано Nescaffe - так что это тоже не пойдет :) Даже если таковые имеются, для моей простой необходимости - они будут излишними и медленными.
Тем не менее, для меня чрезвычайно важно получить много переменных из ответа моего модема в формате json. Я делаю это в sh с очень урезанным BusyBox на моих маршрутизаторах! Нет проблем с использованием только awk: просто установите разделители и прочитайте данные. Для одной переменной это все!
awk 'BEGIN { FS="\""; RS="," }; { if ($2 == "login") {print $4} }' test.json
Помните, у меня нет массивов? Я должен был присвоить анализируемые в awk данные 11 переменным, которые мне нужны в сценарии оболочки. Куда бы я ни посмотрел, это считалось невыполнимой миссией. С этим тоже проблем нет.
Мое решение простое. Этот код будет: 1) анализировать файл .json из вопроса (на самом деле, я позаимствовал образец рабочих данных из наиболее часто задаваемого ответа) и выбрать данные в кавычках, плюс 2) создать переменные оболочки из awk, присваивая свободную именованную оболочку имена переменных.
eval $( curl -s 'https://api.github.com/users/lambda' |
awk ' BEGIN { FS="\""; RS="," };
{
if ($2 == "login") { print "Login=\""$4"\"" }
if ($2 == "name") { print "Name=\""$4"\"" }
if ($2 == "updated_at") { print "Updated=\""$4"\"" }
}' )
echo "$Login, $Name, $Updated"
Никаких проблем с пробелами внутри. В моем случае эта же команда анализирует длинный однострочный вывод. Поскольку используется eval, это решение подходит только для доверенных данных. Его легко адаптировать к данным без кавычек. Для огромного числа переменных, предельное увеличение скорости может быть достигнуто с помощью else if. Отсутствие массива, очевидно, означает: нет нескольких записей без лишних действий. Но там, где имеются массивы, адаптация этого решения - простая задача.
Ответ @maikel sed почти работает (но я не могу это комментировать). Для моих красиво отформатированных данных - это работает. Не так много с примером, использованным здесь (пропущенные кавычки отбрасывают его). Это сложно и сложно изменить. Кроме того, мне не нравится делать 11 вызовов для извлечения 11 переменных. Почему? Я рассчитал 100 циклов, извлекая 9 переменных: функция sed заняла 48,99 с, а мое решение заняло 0,91 с! Не честно? Выполнение только одного извлечения из 9 переменных: 0,51 против 0,02 сек.