Нагадаємо, що програма jq - це конвеєр виразів.
Присвоєння змінної підкоряється такому правилу: присвоєння змінної - це вираз, який має такий вигляд:
... | expr as $varname | ...
Як і вираз тотожності ., присвоєння змінної повертає на виході ті самі дані, що отримує на вході.
Встановлення значення змінної - це побічний ефект.
Приклад, що показує: . після присвоєння - це ті самі дані, що й початковий вхід:
$ jq -c -n '42 | (. * 2) as $double | [., $double]'
[42,84]
Область видимості змінної є «лексичною»: змінна залишається видимою до кінця конвеєра. Змінні, визначені у функціях (до функцій ми дійдемо пізніше), є «локальними» для цієї функції.
Назва змінної має починатися з $.
Решта назви змінної - це ідентифікатор: він починається з літери або підкреслення, за якими йдуть літери, цифри або підкреслення.
З документації:
За допомогою одного виразу
asможна оголосити кілька змінних, надавши шаблон, який відповідає структурі вхідних даних (це називають «деструктуризацією»).
Приклади:
[1, 2, 3] as [$a, $b, $c]
| [$a, $b, $c] # => [1, 2, 3]
{"foo": "bar", "len": [10, 20]} as {foo: $f, len: [$h, $w]}
| [$f, $h, $w] # => ["bar", 10, 20]
Збіг назви змінної з ключем обʼєкта дає змогу скористатися скороченням:
{"x": 4, "y": 7} as {$x, $y}
| [$x, $y] # => [4, 7]
{"foo": "bar", "len": [10, 20]} as {$foo, $len}
| [$foo, $len] # => ["bar", [10, 20]]
Те саме скорочення працює у зворотному напрямку й для конструювання обʼєктів
4 as $x | 7 as $y | {$x, $y} # => {"x":4, "y": 7}
Як видно з наведеного вище прикладу, змінні зручні для зберігання констант. Краще дати константам імʼя, ніж допускати появу «магічних чисел» у коді.
Часто код стає зрозумілішим, якщо обійтися без змінних.
Розглянемо обчислення середнього значення масиву чисел
[2, 4, 8, 7]
| add as $sum
| length as $len
| $sum / $len
порівняно з
[2, 4, 8, 7] | add / length
Це демонструє одну з найпотужніших рис jq: вхідні дані фільтра передаються кожному підвиразу:
[2,4,8,7] передається у add (який додає числа, застосовуючи оператор + до всіх елементів)[2,4,8,7] також передається в length
jq, які знадобляться для цієї вправи//
Вираз a // b видає b, якщо a має значення false або null, а інакше видає a.
У контексті присвоєння змінної це дуже зручно, коли потрібно задати типове значення:
(.input.theAnswer // 42) as $answer | ...
+, -, * - це звичайні оператори додавання, віднімання та множення чисел.У цій вправі ми напишемо трохи коду, який допоможе приготувати чудову лазанью з улюбленої книги рецептів.
На нас чекають чотири завдання, і всі вони повʼязані з часом, витраченим на приготування лазаньї.
Визначте константу з назвою $expected_minutes_in_oven.
Згідно з книгою рецептів, очікуваний час запікання в духовці становить 40 хвилин:
$ jq -n -f lasagna.jq
{
"expected_minutes_in_oven": 40,
...
Це значення приймає як вхідні дані фактичну кількість хвилин, які лазанья вже провела в духовці, і повертає, скільки хвилин їй ще залишилося там провести, виходячи з очікуваного часу в духовці з попереднього завдання.
$ echo '{"actual_minutes_in_oven": 18}' | jq -f lasagna.jq
{
"expected_minutes_in_oven": 40,
"remaining_minutes_in_oven": 22,
...
Час підготовки показує, скільки часу потрібно, щоб підготувати лазанью, перш ніж поставити її в духовку. На підготовку кожного шару потрібно 2 хвилини.
$ echo '{"number_of_layers": 3}' | jq -f lasagna.jq
{
...
"preparation_time": 6,
...
Обчисліть, скільки хвилин загалом ми витратили на приготування лазаньї. Це сума часу підготовки в хвилинах і часу, який лазанья на цей момент уже провела в духовці.
$ echo '{"actual_minutes_in_oven": 10, "number_of_layers": 2}' | jq -f lasagna.jq
{
...
"total_time": 14,
...
Зареєструйтеся на Exercism, щоб вивчати й опановувати jq, а також 12 концепцій75 вправ та справжнє наставництво від людей, і все це безкоштовно.