Pular para o conteúdo

jq e yq

automacao

yq (versão em Go, de Mike Farah) usa a mesma gramática do jq aplicada a YAML.

Filtro O que faz
. Tudo (formata e colore)
.campo Um campo
.campo.subcampo Aninhado
.campo? Não falha se não existir
.[] Itera sobre array ou objeto
.[0], .[-1], .[2:5] Índice, último, fatia
.["chave-com-hifen"] Chave com caractere especial
.. Recursivo (todos os níveis)
keys, keys_unsorted Chaves do objeto
length Tamanho de array, string ou objeto
has("campo") Testa existência
Janela do terminal
jq '.items[] | select(.status == "ativo")' dados.json
jq '.[] | select(.idade > 30 and .cidade == "Recife")' dados.json
jq '.[] | select(.nome | test("^admin"))' dados.json # regex
jq '.[] | select(.tags | index("prod"))' dados.json # array contém
jq 'map(select(.ativo)) | length' dados.json # conta os que passam
jq '.items[] | select(.erro != null)' dados.json
Janela do terminal
jq '.items | map({nome: .metadata.name, no: .spec.nodeName})' dados.json
jq '.[] | "\(.nome): \(.valor)"' dados.json # interpolação em string
jq -r '.[] | [.nome, .valor] | @tsv' dados.json # colunas separadas por tab
jq -r '.[] | @csv' dados.json
jq 'group_by(.time) | map({time: .[0].time, total: length})' dados.json
jq 'sort_by(.criado_em) | reverse | .[:5]' dados.json
jq '[.[] | .custo] | add' dados.json # soma
jq 'to_entries | map("\(.key)=\(.value)")' mapa.json
jq -s 'add' a.json b.json # junta arquivos (slurp)
Flag Efeito
-r String sem aspas (essencial para usar em shell)
-c Compacto, uma linha
-e Código de saída 1 se o resultado for falso/nulo (útil em CI)
-n Não lê entrada (jq -n '{a:1}')
-s Lê todas as entradas como um array
--arg nome valor Passa variável string ($nome)
--argjson nome '{...}' Passa variável JSON
--tab / --indent 4 Formatação
Janela do terminal
# use --arg em vez de interpolar no shell (evita injeção e problemas de aspas)
jq --arg ns "loja" '.items[] | select(.metadata.namespace == $ns)' dados.json
Janela do terminal
# Pods com muitos reinícios
kubectl get pods -A -o json | jq -r '.items[]
| select(.status.containerStatuses[]?.restartCount > 5)
| "\(.metadata.namespace)/\(.metadata.name) \(.status.containerStatuses[0].restartCount)"'
# containers sem limite de memória
kubectl get pods -A -o json | jq -r '.items[]
| .metadata.namespace as $ns | .metadata.name as $pod
| .spec.containers[] | select(.resources.limits.memory == null)
| "\($ns)/\($pod) \(.name)"'
# imagens em uso, únicas
kubectl get pods -A -o json | jq -r '.items[].spec.containers[].image' | sort -u
# quem tem cluster-admin
kubectl get clusterrolebindings -o json | jq -r '.items[]
| select(.roleRef.name == "cluster-admin")
| "\(.metadata.name): \(.subjects // [] | map(.kind + "/" + .name) | join(", "))"'
# plano do Terraform: recursos que serão destruídos
jq -r '.resource_changes[]
| select(.change.actions | index("delete")) | .address' plano.json
Janela do terminal
yq '.spec.replicas' deployment.yaml
yq -i '.spec.replicas = 5' deployment.yaml # edita no arquivo
yq -i '.metadata.labels.time = "loja"' deployment.yaml
yq 'select(.kind == "Deployment")' manifests.yaml # multi-documento
yq ea '[.]' *.yaml # junta documentos
yq -o=json '.' arquivo.yaml # YAML → JSON
yq -P '.' arquivo.json # JSON → YAML
yq '.. | select(has("image")) | .image' manifests.yaml

Diferenças úteis: yq preserva comentários na edição in-place, entende documentos separados por --- e aceita -o=json/-P para converter formatos.

  • Sem -r, a saída vem com aspas e quebra o uso em variáveis de shell.
  • .items[] falha se items for nulo; use .items[]? ou // [].
  • Existem dois yq populares (Go e Python). A sintaxe muda; confira com yq --version.
  • jq não preserva a ordem original das chaves ao reconstruir objetos.
  • Números grandes podem perder precisão ao passar por conversão de ponto flutuante.
  • Em yq -i, faça backup antes: a edição é no lugar.