jq é o sed para JSON — um processador de linha de comando leve e flexível que transforma respostas de API bagunçadas e arquivos de configuração exatamente nos dados que você precisa. Se você já apertou os olhos para uma parede de JSON minificado tentando encontrar um campo aninhado, jq é a ferramenta que faz você se perguntar como sobreviveu sem ela.
O modelo mental é simples: jq é um pipeline. Dados fluem da esquerda, são transformados por filtros e saem do lado direito. O . é seu ponto de partida — significa "toda a entrada." A partir daí você aprofunda com .field, itera com .[] e encadeia filtros com |. É programação funcional disfarçada de ferramenta de linha de comando, e quando o pensamento em pipe clica, você vai pegar o jq como pega o grep.
Organizamos tudo pelo tipo de problema que você está resolvendo em vez da taxonomia interna do jq. Comece com Filtros Básicos para extrair valores de JSON, depois passe para Operações de Array e Objeto quando precisar remodelar dados. A seção de One-Liners no final é onde a mágica real acontece — padrões testados em batalha que você pode copiar e colar no seu terminal agora mesmo.
Uma coisa para internalizar cedo: expressões jq são combináveis. Cada filtro recebe entrada e produz saída, então você pode encadeá-los infinitamente com |. Aquele select(...) que você escreveu? Passe por pipe para map(...). Passe por pipe para sort_by(...). São filtros até o fim.
Filtros Básicos
.
Identidade — retornar toda a entrada sem alterações.field
Extrair um campo de nível superior pelo nome.field.nested
Aprofundar em objetos aninhados com notação de ponto.["hyphenated-key"]
Acessar campos com caracteres especiais no nome.[]
Iterar sobre todos os elementos de um array ou valores de um objeto.[0]
Obter o primeiro elemento de um array.[-1]
Obter o último elemento de um array.[2:5]
Fatiar um array — elementos nos índices 2, 3 e 4.field?
Tentar acessar um campo — suprimir erros se não existir.[] | .name
Iterar um array e extrair um campo de cada elemento
Tipos e Valores
length
Comprimento da string, contagem do array ou número de chaves do objetokeys
Obter todas as chaves de um objeto como um array ordenadokeys_unsorted
Obter todas as chaves de um objeto na ordem originalvalues
Obter todos os valores de um objeto como um arraytype
Retornar o tipo como string: "object", "array", "string", "number", "boolean" ou "null"has("field")
Verificar se um objeto tem uma chave específica (retorna true/false)in({"a":1})
Verificar se uma chave existe em um objeto dadoempty
Não produzir saída — útil para supressão condicionalenv.VAR
Acessar variável de ambiente VAR
Operações com Strings
split(",")
Dividir uma string pelo delimitador em um arrayjoin(",")
Juntar um array de strings com um delimitadortest("regex")
Testar se uma string corresponde a uma regex (retorna true/false)match("regex")
Retornar objeto de correspondência com offset, comprimento e capturascapture("(?<name>\\w+)")
Grupos de captura nomeados retornados como objetogsub("old"; "new")
Substituir todas as ocorrências de um padrão regexsub("old"; "new")
Substituir primeira ocorrência de um padrão regexascii_downcase
Converter string para minúsculasascii_upcase
Converter string para maiúsculasltrimstr("prefix")
Remover um prefixo de uma string se presentertrimstr("suffix")
Remover um sufixo de uma string se presente@base64
Codificar uma string como base64@base64d
Decodificar uma string base64@uri
Codificar uma string em percent-encoding para URLs@html
Escapar caracteres especiais HTMLtostring
Converter qualquer valor para sua representação em stringtonumber
Parsear uma string como número
Operações com Arrays
map(f)
Aplicar filtro f a cada elemento e coletar resultadosmap_values(f)
Aplicar filtro f a cada valor (funciona em objetos também)select(condition)
Manter apenas elementos onde a condição é verdadeirasort
Ordenar um array de valores comparáveissort_by(.field)
Ordenar array de objetos por um campo específicoreverse
Inverter a ordem de um arraygroup_by(.field)
Agrupar elementos do array por um campo em sub-arraysunique
Remover valores duplicados de um array ordenadounique_by(.field)
Remover duplicatas por um campo específicoflatten
Achatar arrays aninhados em um único nívelflatten(1)
Achatar um nível de aninhamentofirst
Obter a primeira saída de um geradorlast
Obter a última saída de um geradorlimit(n; expr)
Pegar apenas as primeiras n saídas de uma expressãoadd
Somar números, concatenar strings ou mesclar arrays/objetosany(condition)
Verdadeiro se algum elemento satisfaz a condiçãoall(condition)
Verdadeiro se todos os elementos satisfazem a condiçãomin_by(.field)
Obter o elemento com o menor valor do campomax_by(.field)
Obter o elemento com o maior valor do campoindices(value)
Obter todos os índices onde o valor aparece no arraycontains([values])
Verificar se o array contém todos os valores especificadosinside([values])
Verificar se a entrada está contida no valor dado
Operações com Objetos
to_entries
Converter {"a":1} para [{"key":"a","value":1}]from_entries
Converter [{"key":"a","value":1}] de volta para {"a":1}with_entries(f)
Atalho para to_entries | map(f) | from_entries+ (objects)
Mesclar dois objetos — lado direito vence em conflitos de chave* (objects)
Mesclar recursivamente dois objetos{name, age}
Selecionar campos específicos de um objeto{newname: .oldname}
Renomear um campo ao extrairdel(.field)
Remover um campo de um objetopaths
Listar todos os caminhos até valores folha como arraysgetpath(["a","b"])
Obter valor em um caminho específico — como .a.bsetpath(["a","b"]; val)
Definir valor em um caminho específicodelpaths([path])
Deletar valores nos caminhos especificados
Condicionais e Comparações
if . then A else B end
Expressão condicional — cláusula else é opcional// (alternative)
Usar valor da direita se o da esquerda for null ou falsea == b
Comparação de igualdade (igualdade profunda para objetos/arrays)a != b
Comparação de desigualdadeand, or, not
Operadores booleanostry f
Executar filtro f, suprimir erros silenciosamentetry f catch msg
Executar filtro f, usar expressão msg em caso de errof as $var | expr
Vincular um valor a uma variável para uso no pipelinereduce .[] as $x (init; update)
Reduzir um array a um único valorlabel $out | foreach ...
Loop com streaming e suporte a break
Formatação de Saída
-r (--raw-output)
Exibir strings brutas sem aspas JSON-c (--compact-output)
Minificar — imprimir JSON em uma única linha-S (--sort-keys)
Ordenar chaves de objetos alfabeticamente na saída-e (--exit-status)
Definir código de saída baseado na saída: 0 para true/não-null, 1 para false/null-n (--null-input)
Não ler entrada — útil com --argjson ou --slurpfile-s (--slurp)
Ler todas as entradas em um único array--arg name val
Passar um valor string como variável $name--argjson name val
Passar um valor JSON como variável $name--slurpfile name file
Carregar um arquivo JSON como variável $name (array)@csv
Formatar um array de arrays como CSV@tsv
Formatar um array de arrays como TSV@json
Serializar um valor como string JSON (para embutir)@text
Converter para saída de texto
One-Liners
Padrões do mundo real que você vai realmente usar. Copie, cole, adapte.
One-Liners
jq . file.json
Formatar um arquivo JSON (pretty-print)jq -r ".[] | .name" file.json
Extrair um campo de cada objeto em um arrayjq "[.[] | select(.active == true)]"
Filtrar um array para apenas elementos correspondentesjq -r ".[] | [.name, .email] | @csv"
Converter array JSON para CSVjq -s "." file1.json file2.json
Mesclar múltiplos arquivos JSON em um arrayjq -r "keys[]" file.json
Listar todas as chaves de nível superiorjq ".[] | select(.price > 100) | .name"
Encontrar nomes onde o preço excede um limitejq "group_by(.status) | map({(.[0].status): length}) | add"
Contar itens por grupojq --arg q "$QUERY" '.[] | select(.name | test($q; "i"))'
Busca case-insensitive usando uma variável do shelljq -r "to_entries[] | \"\(.key)=\(.value)\""
Converter objeto JSON para linhas chave=valorjq "[.[] | {id, name}]"
Remodelar objetos — manter apenas campos específicosjq -r ".results | sort_by(.date) | reverse | .[0]"
Obter a entrada mais recente de um array ordenadocurl -s api.example.com | jq .
Formatar resposta de API inlinejq -s "map(.items) | flatten | unique_by(.id)"
Mesclar e deduplicar respostas paginadas de APIjq 'walk(if type == "string" then gsub("\\n"; " ") else . end)'
Limpar recursivamente quebras de linha em todos os valores string
Use -r (raw output) sempre que fizer pipe do jq para outro comando. Sem isso, strings vêm entre aspas, e essas aspas vão assombrar seus scripts de shell. jq -r '.name' te dá Alice, não "Alice".
O operador // é o null coalescing do jq — retorna o lado direito quando o esquerdo é null ou false. Perfeito para valores padrão: .config.timeout // 30. É um daqueles combos de dois caracteres que te poupa de escrever um if-then-else completo noventa por cento das vezes.
Quando precisar combinar dados de múltiplos arquivos ou respostas de API, use --slurp (-s). Ele lê todas as entradas em um único array, então você pode mesclar objetos com add, achatar arrays ou cruzar dados entre arquivos.
Use --arg e --argjson para passar variáveis do shell para o jq com segurança. Nunca interpole variáveis do shell diretamente em expressões jq — isso quebra com caracteres especiais e te expõe a injeção. jq --arg name "$USER" '.[] | select(.name == $name)' é o jeito certo.
O filtro @base64d é salvador quando se trabalha com secrets do Kubernetes ou JWTs. Passe um valor codificado em base64 por jq -r '.data.password | @base64d' e obtenha o texto puro sem sair do pipeline.
Encadeie to_entries, map e from_entries (ou use o atalho with_entries) para transformar chaves e valores de objetos em uma passada. Quer prefixar toda chave? with_entries(.key = "prefix_" + .key). É o equivalente de objeto do map para arrays.
Se as mensagens de erro do jq são crípticas, adicione debug em qualquer lugar do seu pipeline para ver o que está fluindo naquele ponto. Ele imprime no stderr sem atrapalhar sua saída. Pense nele como console.log para jq: .[] | debug | select(.active).