Voltar ao Diminua Blog

Artigo

Dominando o `jq` no Linux: Manipulação e Transformação de Dados JSON no Terminal

Um guia prático para extrair, filtrar e transformar dados JSON de forma eficiente diretamente da linha de comando.

Dominando o `jq` no Linux: Manipulação e Transformação de Dados JSON no Terminal

Introdução ao `jq`

No universo do desenvolvimento e da administração de sistemas, lidar com dados em formato JSON (JavaScript Object Notation) é uma constante. Seja consumindo APIs, configurando aplicações ou analisando logs, o JSON se tornou um padrão de fato para a troca de informações estruturadas. Para quem trabalha na linha de comando do Linux, o jq surge como uma ferramenta indispensável para navegar, filtrar e manipular esses dados de forma poderosa e flexível.

O jq é um processador JSON leve e de linha de comando. Ele permite que você corte, filtre, mapeie e transforme dados JSON de maneira intuitiva. Se você já se sentiu perdido ao tentar extrair uma informação específica de uma resposta JSON longa ou se deseja formatar dados JSON para melhor legibilidade, o jq é a solução.

Instalação do `jq`

A instalação do jq é geralmente simples na maioria das distribuições Linux. Para sistemas baseados em Debian/Ubuntu, você pode usar o gerenciador de pacotes apt:

sudo apt update
sudo apt install jq

Em distribuições baseadas em Red Hat/Fedora, o comando seria:

sudo dnf install jq

Ou, para versões mais antigas:

sudo yum install jq

Após a instalação, você pode verificar se o jq está funcionando corretamente executando:

jq --version

Isso exibirá a versão instalada do jq.

Conceitos Fundamentais do `jq`

A força do jq reside em sua linguagem de filtro. Os filtros são aplicados a um objeto JSON de entrada e produzem uma saída JSON. Alguns filtros básicos incluem:

  • .: O filtro identidade, que simplesmente retorna a entrada JSON inalterada. Útil para formatar a saída JSON de forma legível.
  • .campo: Seleciona o valor associado a uma chave específica em um objeto JSON.
  • .[indice]: Seleciona um elemento de um array JSON pelo seu índice (baseado em zero).
  • .campo1, .campo2: Seleciona múltiplos campos.
  • .[]: Itera sobre todos os elementos de um array JSON ou todos os valores de um objeto JSON.

Vamos considerar um exemplo de JSON para ilustrar:

{
  "nome": "Exemplo de Projeto",
  "versao": "1.0.0",
  "autores": [
    {"nome": "Alice", "email": "[email protected]"},
    {"nome": "Bob", "email": "[email protected]"}
  ],
  "dependencias": {
    "frontend": "React",
    "backend": "Node.js"
  }
}

Exemplos de Uso Básico

Para obter o nome do projeto:

echo '{ "nome": "Exemplo de Projeto", "versao": "1.0.0" }' | jq '.nome'

Saída: "Exemplo de Projeto"

Para obter o nome do primeiro autor:

echo '{
  "nome": "Exemplo de Projeto",
  "autores": [
    {"nome": "Alice", "email": "[email protected]"},
    {"nome": "Bob", "email": "[email protected]"}
  ]
}' | jq '.autores[0].nome'

Saída: "Alice"

Para obter todos os nomes dos autores:

echo '{
  "nome": "Exemplo de Projeto",
  "autores": [
    {"nome": "Alice", "email": "[email protected]"},
    {"nome": "Bob", "email": "[email protected]"}
  ]
}' | jq '.autores[].nome'

Saída:

"Alice"
"Bob"

Filtragem e Seleção Avançada

O jq oferece recursos poderosos para filtrar dados com base em condições.

Filtrando Arrays com `select()`

A função select(condicao) permite filtrar elementos de um array que satisfazem uma determinada condição. Por exemplo, para encontrar o autor chamado 'Bob':

echo '{
  "autores": [
    {"nome": "Alice", "email": "[email protected]"},
    {"nome": "Bob", "email": "[email protected]"}
  ]
}' | jq '.autores[] | select(.nome == "Bob")'

Saída:

{
  "nome": "Bob",
  "email": "[email protected]"
}

Criando Novos Objetos JSON

Você pode usar o jq para construir novos objetos JSON a partir dos dados de entrada. Por exemplo, para extrair apenas o nome e o email de todos os autores:

echo '{
  "autores": [
    {"nome": "Alice", "email": "[email protected]"},
    {"nome": "Bob", "email": "[email protected]"}
  ]
}' | jq '.autores[] | {nome: .nome, email: .email}'

Saída:

{
  "nome": "Alice",
  "email": "[email protected]"
}
{
  "nome": "Bob",
  "email": "[email protected]"
}

Note que, por padrão, o jq exibe cada objeto resultante em uma linha separada quando o resultado é uma sequência de objetos. Para obter um array de objetos, podemos envolver a expressão entre colchetes:

echo '{
  "autores": [
    {"nome": "Alice", "email": "[email protected]"},
    {"nome": "Bob", "email": "[email protected]"}
  ]
}' | jq '[ .autores[] | {nome: .nome, email: .email} ]'

Saída:

[
  {
    "nome": "Alice",
    "email": "[email protected]"
  },
  {
    "nome": "Bob",
    "email": "[email protected]"
  }
]

Transformação e Agregação de Dados

O jq é excelente para transformar dados de um formato para outro e para realizar agregações.

Mapeamento de Campos

Podemos renomear campos ou criar campos derivados. Por exemplo, para criar um novo campo que combine nome e email:

echo '{
  "autores": [
    {"nome": "Alice", "email": "[email protected]"}
  ]
}' | jq '.autores[] | {autor: .nome, contato: .email}'

Saída:

{
  "autor": "Alice",
  "contato": "[email protected]"
}

Contagem de Elementos

Para contar quantos autores existem no nosso exemplo JSON:

echo '{
  "autores": [
    {"nome": "Alice", "email": "[email protected]"},
    {"nome": "Bob", "email": "[email protected]"}
  ]
}' | jq '.autores | length'

Saída: 2

Uso em Pipelines de DevOps

O jq brilha quando integrado em scripts e pipelines de CI/CD. Ele permite processar a saída de comandos como curl, aws cli, gcloud cli, etc., que frequentemente retornam dados em JSON.

Exemplo: Extraindo informações de uma API com `curl`

Suponha que você precise obter o nome de usuário de um repositório GitHub:

curl -s 'https://api.github.com/repos/stedolan/jq' | jq '.owner.login'

Este comando usa curl para buscar os dados do repositório (-s para modo silencioso) e, em seguida, jq para extrair o login do proprietário do repositório.

Aviso de Segurança: Ao interagir com APIs que requerem autenticação, nunca exponha suas credenciais diretamente na linha de comando ou em scripts de forma insegura. Utilize variáveis de ambiente, tokens de acesso ou mecanismos seguros de gerenciamento de segredos.

Exemplo: Processando logs JSON

Se seus logs são gerados em formato JSON, o jq pode ser usado para filtrar e analisar eventos específicos. Por exemplo, para encontrar todos os logs de erro (assumindo um campo level):

cat meu_log.jsonl | jq 'select(.level == "error")'

Assumindo que meu_log.jsonl contém um JSON por linha (JSON Lines).

Considerações Finais e Boas Práticas

O jq é uma ferramenta extremamente versátil que pode simplificar significativamente o trabalho com dados JSON na linha de comando. Algumas boas práticas incluem:

  • Legibilidade: Use o jq com a opção -r (raw output) quando quiser obter strings sem aspas, ou use filtros como .campo | @tsv para formatar a saída em TSV (Tab Separated Values), facilitando a leitura ou o processamento por outras ferramentas.
  • Complexidade: Para filtros muito complexos, considere escrever um script separado ou usar a opção -f arquivo.jq para carregar um filtro de um arquivo, melhorando a organização.
  • Entrada e Saída: Lembre-se que o jq espera JSON válido como entrada. Se a entrada não for JSON, ele falhará. Use ferramentas como python -m json.tool ou o próprio jq com o filtro . para formatar e validar a entrada antes de processá-la.
  • Performance: Para arquivos JSON muito grandes, o jq pode consumir bastante memória. Em cenários de Big Data, ferramentas mais especializadas podem ser necessárias, mas para a maioria dos projetos pequenos e médios, o jq é mais do que suficiente.

Dominar o jq é um passo importante para qualquer profissional que lida com dados estruturados no ambiente Linux. Ele não apenas economiza tempo, mas também aumenta a precisão e a eficiência na manipulação de informações.

Foto de RealToughCandy.com no Pexels.