jq e yq
yq (versão em Go, de Mike Farah) usa a mesma gramática do jq aplicada a YAML.
Seleção
Seção intitulada “Seleção”| 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 |
Filtrar
Seção intitulada “Filtrar”jq '.items[] | select(.status == "ativo")' dados.jsonjq '.[] | select(.idade > 30 and .cidade == "Recife")' dados.jsonjq '.[] | select(.nome | test("^admin"))' dados.json # regexjq '.[] | select(.tags | index("prod"))' dados.json # array contémjq 'map(select(.ativo)) | length' dados.json # conta os que passamjq '.items[] | select(.erro != null)' dados.jsonTransformar
Seção intitulada “Transformar”jq '.items | map({nome: .metadata.name, no: .spec.nodeName})' dados.jsonjq '.[] | "\(.nome): \(.valor)"' dados.json # interpolação em stringjq -r '.[] | [.nome, .valor] | @tsv' dados.json # colunas separadas por tabjq -r '.[] | @csv' dados.jsonjq 'group_by(.time) | map({time: .[0].time, total: length})' dados.jsonjq 'sort_by(.criado_em) | reverse | .[:5]' dados.jsonjq '[.[] | .custo] | add' dados.json # somajq 'to_entries | map("\(.key)=\(.value)")' mapa.jsonjq -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 |
# 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.jsonReceitas com kubectl
Seção intitulada “Receitas com kubectl”# Pods com muitos reinícioskubectl 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óriakubectl 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, únicaskubectl get pods -A -o json | jq -r '.items[].spec.containers[].image' | sort -u
# quem tem cluster-adminkubectl 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ídosjq -r '.resource_changes[] | select(.change.actions | index("delete")) | .address' plano.jsonyq para YAML
Seção intitulada “yq para YAML”yq '.spec.replicas' deployment.yamlyq -i '.spec.replicas = 5' deployment.yaml # edita no arquivoyq -i '.metadata.labels.time = "loja"' deployment.yamlyq 'select(.kind == "Deployment")' manifests.yaml # multi-documentoyq ea '[.]' *.yaml # junta documentosyq -o=json '.' arquivo.yaml # YAML → JSONyq -P '.' arquivo.json # JSON → YAMLyq '.. | select(has("image")) | .image' manifests.yamlDiferenças úteis: yq preserva comentários na edição in-place, entende documentos
separados por --- e aceita -o=json/-P para converter formatos.
Pegadinhas
Seção intitulada “Pegadinhas”- Sem
-r, a saída vem com aspas e quebra o uso em variáveis de shell. .items[]falha seitemsfor nulo; use.items[]?ou// [].- Existem dois
yqpopulares (Go e Python). A sintaxe muda; confira comyq --version. jqnã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.