Lembra-te de que um programa jq é um pipeline de expressões.
A atribuição de variáveis segue esta regra: uma atribuição de variável é uma expressão com este aspeto:
... | expr as $varname | ...
Tal como a expressão de identidade ., a saída da atribuição de variável é igual à sua entrada.
Definir o valor da variável é um efeito secundário.
Exemplo que mostra que ., depois da atribuição, é igual à entrada inicial:
$ jq -c -n '42 | (. * 2) as $double | [., $double]'
[42,84]
O âmbito da variável é «lexical»: a variável permanece no âmbito até ao fim do pipeline. As variáveis definidas em funções (falaremos de funções mais adiante) são «locais» à função.
A variável tem de começar por $.
O resto do nome da variável é um identificador: começa por uma letra ou um underscore, seguido de letras, números ou underscores.
Do manual:
É possível declarar várias variáveis com uma única expressão
as, fornecendo um padrão que corresponda à estrutura da entrada (isto é conhecido como «desestruturação»).
Exemplos:
[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]
Fazer corresponder o nome da variável à chave do objeto oferece um atalho:
{"x": 4, "y": 7} as {$x, $y}
| [$x, $y] # => [4, 7]
{"foo": "bar", "len": [10, 20]} as {$foo, $len}
| [$foo, $len] # => ["bar", [10, 20]]
O mesmo atalho funciona no sentido inverso para a construção de objetos
4 as $x | 7 as $y | {$x, $y} # => {"x":4, "y": 7}
Como se vê no exemplo acima, as variáveis são úteis para guardar constantes. É melhor dar um nome às constantes do que deixar «números mágicos» aparecerem no código.
Muitas vezes, omitir variáveis torna o código mais legível.
Considera o cálculo da média de uma lista de números
[2, 4, 8, 7]
| add as $sum
| length as $len
| $sum / $len
em comparação com
[2, 4, 8, 7] | add / length
Isto realça um dos aspetos mais poderosos do jq: a entrada de um filtro é disponibilizada a todas as subexpressões:
[2,4,8,7] é passado a add (que soma os números aplicando o operador + a todos os elementos)[2,4,8,7] também é passado a length
jq necessários para o exercício de aprendizagem//
A expressão a // b produz b se a for false ou null; caso contrário, produz a.
No contexto de definir uma variável, isto é muito útil para fornecer um valor por omissão:
(.input.theAnswer // 42) as $answer | ...
+, -, * são os habituais operadores numéricos de adição, subtração e multiplicação.Neste exercício vais escrever algum código para te ajudar a fazer uma lasanha fantástica a partir do teu livro de receitas preferido.
Tens quatro tarefas, todas relacionadas com o tempo gasto a cozinhar a lasanha.
Define uma constante chamada $expected_minutes_in_oven.
De acordo com o livro de receitas, o tempo esperado no forno é de 40 minutos:
$ jq -n -f lasagna.jq
{
"expected_minutes_in_oven": 40,
...
Este valor recebe como valor de entrada os minutos reais que a lasanha já passou no forno e devolve quantos minutos a lasanha ainda tem de ficar no forno, com base no tempo esperado no forno em minutos da tarefa anterior.
$ echo '{"actual_minutes_in_oven": 18}' | jq -f lasagna.jq
{
"expected_minutes_in_oven": 40,
"remaining_minutes_in_oven": 22,
...
O tempo de preparação é quanto demora a preparar a lasanha antes de a colocar no forno. Demora 2 minutos a preparar cada camada.
$ echo '{"number_of_layers": 3}' | jq -f lasagna.jq
{
...
"preparation_time": 6,
...
Calcula quantos minutos, no total, dedicaste a cozinhar a lasanha. É a soma do tempo de preparação em minutos com o tempo, em minutos, que a lasanha já passou no forno até agora.
$ echo '{"actual_minutes_in_oven": 10, "number_of_layers": 2}' | jq -f lasagna.jq
{
...
"total_time": 14,
...
Inscreve-te no Exercism para aprenderes e dominares jq com 12 conceitos75 exercícios, e mentoria humana real, tudo grátis.