Como usar jq para processar JSON no terminal
1. Introdução ao jq e sua importância no terminal
jq é um processador JSON leve, flexível e extremamente poderoso para linha de comando. Ele funciona como um "sed para JSON", permitindo filtrar, transformar, agregar e formatar dados JSON de forma declarativa. Sua importância no ecossistema de desenvolvimento moderno é inegável: APIs REST retornam JSON, arquivos de configuração (Docker Compose, Kubernetes) são JSON, logs estruturados seguem esse formato, e ferramentas como curl frequentemente produzem saídas JSON.
Sem jq, manipular JSON no terminal seria um pesadelo de grep, awk e expressões regulares frágeis. Com jq, você escreve filtros concisos e previsíveis.
Instalação rápida:
- Linux (Debian/Ubuntu): sudo apt install jq
- macOS: brew install jq
- Windows: choco install jq ou baixar o binário do site oficial
Verifique a instalação com:
jq --version
Saída esperada: jq-1.7.1 (ou versão similar).
2. Estrutura básica e primeiros comandos
A sintaxe fundamental do jq é:
jq 'filtro' arquivo.json
Ou em pipeline com curl:
curl https://api.example.com/dados | jq '.'
O filtro mais básico é . (ponto), que retorna o JSON inteiro formatado (pretty-print). Sem jq, a saída de curl vem em linha única.
Considere o arquivo pessoa.json:
{"nome": "Ana", "idade": 30, "endereco": {"cidade": "São Paulo", "uf": "SP"}}
Acessando chaves simples:
jq '.nome' pessoa.json
Saída:
"Ana"
Navegação aninhada:
jq '.endereco.cidade' pessoa.json
Saída:
"São Paulo"
O operador | (pipe) permite encadear filtros, similar ao shell:
jq '.endereco | .uf' pessoa.json
3. Filtros de seleção e iteração
Arrays são comuns em JSON. O operador .[] desempacota todos os elementos de um array.
Arquivo usuarios.json:
[
{"nome": "Carlos", "idade": 25},
{"nome": "Maria", "idade": 32},
{"nome": "João", "idade": 28}
]
Desempacotar array:
jq '.[]' usuarios.json
Saída (três objetos separados):
{
"nome": "Carlos",
"idade": 25
}
{
"nome": "Maria",
"idade": 32
}
{
"nome": "João",
"idade": 28
}
Acessar índice específico:
jq '.[0]' usuarios.json
Saída: o primeiro objeto.
Slicing (fatia):
jq '.[1:3]' usuarios.json
Retorna os elementos dos índices 1 e 2 (exclui o 3).
Extrair campos de objetos:
jq '.[] | .nome' usuarios.json
Saída:
"Carlos"
"Maria"
"João"
4. Filtragem condicional com select
O filtro select(condição) mantém apenas objetos que satisfazem a condição.
Filtrar por valor exato:
jq '.[] | select(.idade > 30)' usuarios.json
Saída:
{
"nome": "Maria",
"idade": 32
}
Operadores lógicos:
jq '.[] | select(.idade > 25 and .nome != "Maria")' usuarios.json
Saída:
{
"nome": "João",
"idade": 28
}
Exemplo prático: filtrar usuários ativos em um log JSON:
jq '.[] | select(.status == "ativo")' logs.json
5. Transformação e construção de novos JSON
jq permite criar novos objetos a partir de dados existentes.
Criar objeto simples:
jq '.[] | {nome_completo: .nome, faixa_etaria: if .idade < 30 then "jovem" else "adulto" end}' usuarios.json
Saída:
{
"nome_completo": "Carlos",
"faixa_etaria": "jovem"
}
{
"nome_completo": "Maria",
"faixa_etaria": "adulto"
}
{
"nome_completo": "João",
"faixa_etaria": "jovem"
}
Adicionar chave:
jq '.[] | . += {"ativo": true}' usuarios.json
Remover chave:
jq '.[] | del(.idade)' usuarios.json
6. Agregação e cálculos com jq
Funções de redução permitem sumarizar dados.
Comprimento de array:
jq 'length' usuarios.json
Saída: 3
Somar valores numéricos:
jq '[.[] | .idade] | add' usuarios.json
Saída: 85
Agrupamento (group_by):
Arquivo vendas.json:
[
{"produto": "caneta", "quantidade": 10},
{"produto": "lapis", "quantidade": 5},
{"produto": "caneta", "quantidade": 7}
]
jq 'group_by(.produto) | map({produto: .[0].produto, total: map(.quantidade) | add})' vendas.json
Saída:
[
{
"produto": "caneta",
"total": 17
},
{
"produto": "lapis",
"total": 5
}
]
Estatísticas simples:
jq '[.[] | .idade] | min, max, unique' usuarios.json
7. Integração com outras ferramentas do terminal
Combinando com curl:
curl -s https://jsonplaceholder.typicode.com/users | jq '.[] | {nome: .name, email: .email}'
Usando em scripts shell:
for usuario in $(curl -s api.com/usuarios | jq -r '.[].nome'); do
echo "Processando: $usuario"
done
A flag -r (raw) remove as aspas das strings, permitindo uso direto no shell.
Saída compacta com -c:
jq -c '.[] | {nome, idade}' usuarios.json
Útil para logs de uma linha.
8. Boas práticas e dicas avançadas
Tratamento de erros com try e catch:
jq 'try .[].inexistente catch "campo_ausente"' dados.json
Uso de variáveis com --arg:
jq --arg nome "Maria" '.[] | select(.nome == $nome)' usuarios.json
Isso permite filtros dinâmicos sem concatenação de strings no filtro.
Monitoramento de logs JSON em tempo real:
tail -f app.log | jq 'select(.level == "ERROR") | {timestamp: .time, mensagem: .message}'
Boas práticas:
- Sempre coloque filtros entre aspas simples para evitar expansão do shell.
- Use -r quando precisar de saída sem aspas para pipelines.
- Teste filtros com jq interativamente antes de incorporar em scripts.
- Prefira jq a grep/awk para JSON: é semanticamente correto.
jq é uma ferramenta indispensável no cinto de utilidades de qualquer profissional que lida com dados estruturados no terminal. Domine seus filtros e você manipulará JSON com a mesma fluência que manipula texto com sed e awk.
Referências
- jq Manual (oficial) — Documentação completa com todos os filtros, funções e exemplos.
- jq Playground (online) — Ambiente interativo para testar filtros jq sem instalação.
- Como usar jq para processar JSON no Linux - DigitalOcean — Tutorial prático com exemplos do mundo real.
- jq Cookbook — Coletânea de receitas e padrões comuns de uso do jq.
- Processando JSON com jq - Dev.to — Artigo com exemplos avançados de filtragem e transformação.
- Usando jq em pipelines de shell - Linux Journal — Guia sobre integração de jq com scripts shell e outras ferramentas Unix.