Agregação com matrizes e agrupamento no awk
Calcule somas, contagens e resumos por agrupamento usando matrizes associativas indexadas pelos valores dos campos.
Agregação com matrizes e agrupamento no awk é uma aula grátis de Linux Command Line & Bash Scripting Mastery no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Linux Command Line & Bash Scripting Mastery, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Linux Command Line & Bash Scripting Mastery inclui 4 aulas no total.
O que são matrizes associativas do awk?
No awk, uma matriz associativa é um armazenamento de pares chave-valor em que as chaves podem ser qualquer texto ou número. Diferentemente das matrizes indexadas da maioria das linguagens, as matrizes do awk são, internamente, tabelas de dispersão — perfeitas para agrupar e agregar dados por valores de campos.
- Declare implicitamente: basta atribuir
arr[key] = value - As chaves são textos por padrão (os números são convertidos)
- Não há limite de tamanho — o awk aumenta a matriz conforme necessário
- Ideais para calcular somas, contagens e agregações por grupo em uma única passagem
Não é necessário inicializar uma chave antes de incrementá-la — o awk trata automaticamente uma chave não definida como zero ou como uma cadeia vazia.
Contando linhas por grupo
O padrão de agregação mais comum é contar quantas vezes cada valor exclusivo de um campo aparece. Use o campo $1 (ou qualquer outro campo) como chave da matriz e incremente um contador a cada linha correspondente.
O bloco END é executado depois que toda a entrada é consumida — é nele que os resultados acumulados são impressos.
count[$1]++Após o processamento, count contém o número total de linhas para cada valor exclusivo de $1.
#!/usr/bin/env bash
# Count how many log entries exist per HTTP status code
# Input format: <ip> <date> <method> <path> <status> <bytes>
printf '10.0.0.1 2024-01-01 GET /index 200 512
10.0.0.2 2024-01-01 POST /api 404 128
10.0.0.3 2024-01-01 GET /img 200 2048
10.0.0.4 2024-01-01 GET /api 500 64
10.0.0.5 2024-01-01 DELETE /api 404 32
' | awk '
{
count[$5]++
}
END {
for (status in count)
print status, count[status]
}'
Somando um campo numérico por grupo
Contar é apenas uma forma de agregação. Para somar um campo numérico agrupado por outro campo, acumule o valor numérico em uma matriz indexada pelo campo do grupo.
O padrão é:
- Chave = o campo usado para agrupar (por exemplo,
$1para o nome de usuário) - Valor = total acumulado do campo numérico (por exemplo,
$2para bytes)
Isso calcula uma soma completa por grupo em uma única passagem do awk — não é necessário ordenar nem fazer pré-processamento.
#!/usr/bin/env bash
# Sum bytes transferred per user from an access log
printf 'alice 1024
bob 512
alice 2048
charlie 256
bob 768
alice 128
' | awk '
{
bytes[$1] += $2
}
END {
for (user in bytes)
printf "%-10s %d bytes\n", user, bytes[user]
}'
Combinando contagem e soma em uma única passagem
O awk permite manter várias matrizes simultaneamente, fornecendo a contagem e a soma (e, portanto, a média) de cada grupo em uma única leitura do arquivo. Isso é muito mais eficiente do que executar o fluxo duas vezes.
count[key]++— acompanha as ocorrênciastotal[key] += $N— acompanha a soma acumulada- Em
END, dividatotal[k] / count[k]para obter a média por grupo
#!/usr/bin/env bash
# Compute per-department headcount and average salary
printf 'Engineering Alice 95000
Engineering Bob 88000
Marketing Carol 72000
Marketing Dave 68000
Engineering Eve 102000
Marketing Frank 75000
' | awk '
{
dept = $1
sal = $3
count[dept]++
total[dept] += sal
}
END {
printf "%-15s %5s %10s\n", "Department", "Count", "Avg Salary"
for (d in count)
printf "%-15s %5d %10.0f\n", d, count[d], total[d]/count[d]
}'
Chaves com vários campos para agrupamento bidimensional
Você pode criar uma chave composta concatenando vários campos com um separador. Isso fornece um agrupamento bidimensional sem nenhuma sintaxe especial.
Escolha um separador que não possa aparecer nos dados (por exemplo, SUBSEP, o separador de registros integrado do awk \034 ou uma barra vertical literal |).
- Chave composta:
arr[$1 SUBSEP $2]ouarr[$1"|"$2] - Divida novamente a chave ao imprimir:
split(key, parts, "|")
#!/usr/bin/env bash
# Count requests grouped by HTTP method AND status code
printf 'GET 200
POST 201
GET 404
GET 200
DELETE 204
POST 201
GET 404
POST 500
' | awk '
{
key = $1 "|" $2
count[key]++
}
END {
printf "%-8s %-6s %s\n", "Method", "Status", "Count"
for (k in count) {
split(k, parts, "|")
printf "%-8s %-6s %d\n", parts[1], parts[2], count[k]
}
}'
Acompanhando valores mínimos e máximos por grupo
As matrizes associativas facilitam o acompanhamento dos valores mínimo e máximo por grupo. O segredo é inicializar somente na primeira ocorrência de cada chave usando a condição especial !(key in arr).
!(key in min_arr)é verdadeiro na primeira vez que uma chave é encontrada- Após a inicialização, compare e substitua usando a verificação padrão de menor que / maior que
Esse padrão evita um zero indevido que corromperia o valor mínimo.
#!/usr/bin/env bash
# Find min and max response time per endpoint
printf '/api/users 120
/api/orders 340
/api/users 98
/api/orders 512
/api/users 210
/api/orders 280
/health 5
/health 7
' | awk '
{
ep = $1
rt = $2
if (!(ep in mn)) { mn[ep] = rt; mx[ep] = rt }
if (rt < mn[ep]) mn[ep] = rt
if (rt > mx[ep]) mx[ep] = rt
}
END {
printf "%-15s %6s %6s\n", "Endpoint", "Min", "Max"
for (ep in mn)
printf "%-15s %6d %6d\n", ep, mn[ep], mx[ep]
}'
Distribuição de frequências — grupos entre os N primeiros
Uma tarefa comum no mundo real é encontrar os N valores mais frequentes. O awk faz a contagem; canalize a saída por sort e head para classificar e limitar os resultados.
Este padrão de canalização é idiomático na engenharia de shell:
- O awk conta as ocorrências em uma matriz e imprime
count keyemEND sort -rnordena numericamente em ordem decrescentehead -n 5mantém apenas os 5 primeiros
Manter o awk concentrado na agregação e delegar a ordenação a sort segue a filosofia Unix.
#!/usr/bin/env bash
# Top 3 most active IP addresses from an access log
printf '192.168.1.10 GET /index
10.0.0.5 POST /api
192.168.1.10 GET /css
172.16.0.3 GET /index
10.0.0.5 GET /api
192.168.1.10 DELETE /api
172.16.0.3 POST /login
10.0.0.5 GET /index
10.0.0.5 POST /logout
' | awk '{count[$1]++} END {for (ip in count) print count[ip], ip}' \
| sort -rn \
| head -n 3
Usando NR e FNR para agregação em vários arquivos
Ao processar vários arquivos, os valores integrados NR (total de registros lidos) e FNR (registros do arquivo atual) permitem identificar de qual arquivo cada registro veio usando FILENAME.
FILENAME— nome do arquivo que está sendo lido no momentoFNR == 1— é acionado no início de cada novo arquivo (útil para ignorar cabeçalhos)
Isso permite fazer a agregação por grupo, arquivo a arquivo, em um diretório inteiro de registros, com uma única execução do awk.
Imprimindo resultados ordenados de matrizes do awk
O laço for (key in array) do awk não garante uma ordem. Para obter resultados determinísticos, canalize a impressão de END do awk por sort ou reúna os valores e ordene-os dentro do awk usando as funções asorti / asort (somente no GNU awk).
A abordagem portátil de canalização do shell geralmente é preferível em scripts multiplataforma:
sort -k1,1— ordena alfabeticamente pelo primeiro campo (a chave do grupo)sort -k2,2rn— ordena numericamente em ordem decrescente pelo segundo campo (contagem/soma)
#!/usr/bin/env bash
# Bytes per user, sorted alphabetically by username
printf 'zara 800
alice 1500
bob 300
alice 200
zara 400
bob 1100
' | awk '
{
total[$1] += $2
}
END {
for (u in total)
print u, total[u]
}' | sort -k1,1
Excluindo chaves de matrizes e limpando o estado
Às vezes, é necessário redefinir o estado da agregação durante o fluxo — por exemplo, ao processar arquivos de registros em que cada seção é separada por uma linha em branco ou por um valor sentinela.
delete arr[key]— remove uma única entradadelete arr— limpa a matriz inteira (GNU awk)- Verifique a existência com
(key in arr)antes de acessar a chave, para evitar a criação de entradas fantasmas
Essa técnica permite fazer agregações por janela deslizante ou por seção sem reiniciar o awk.
#!/usr/bin/env bash
# Sum values within each section delimited by "---"
printf 'alice 100
bob 200
---
alice 50
bob 75
charlie 300
---
' | awk '
/^---/ {
print "-- Section totals --"
for (u in total) printf " %-10s %d\n", u, total[u]
delete total
next
}
{
total[$1] += $2
}'
Fluxo do mundo real: resumo de registros do Nginx
Reunindo tudo — aqui está uma agregação de nível de produção, feita em uma única passagem do awk, sobre um registro no formato combinado do Nginx. Ela calcula a contagem de solicitações, o total de bytes e a taxa de erros por host virtual em uma única leitura.
Principais técnicas usadas:
- Chave composta:
vhostextraído de um campo - Matrizes paralelas:
reqs[],bytes[],errors[] - Acumulação condicional:
$9 >= 400para contar apenas respostas com erro - Tabela formatada com
printfemEND
#!/usr/bin/env bash
# Simulated Nginx combined log: host ip - - [date] "METHOD /path HTTP/1.1" status bytes
printf 'api.example.com 10.0.0.1 - - [01/Jan/2024] "GET /v1" 200 1024
www.example.com 10.0.0.2 - - [01/Jan/2024] "GET /" 200 4096
api.example.com 10.0.0.3 - - [01/Jan/2024] "POST /v1" 500 128
www.example.com 10.0.0.4 - - [01/Jan/2024] "GET /img" 404 64
api.example.com 10.0.0.5 - - [01/Jan/2024] "GET /v1" 200 2048
www.example.com 10.0.0.6 - - [01/Jan/2024] "GET /" 200 4096
api.example.com 10.0.0.7 - - [01/Jan/2024] "DELETE /v1" 403 32
' | awk '
{
host = $1; status = $9; b = $10
reqs[host]++
bytes[host] += b
if (status + 0 >= 400) errors[host]++
}
END {
printf "%-20s %6s %10s %6s\n", "Host", "Reqs", "Bytes", "Errors"
for (h in reqs)
printf "%-20s %6d %10d %6d\n", h, reqs[h], bytes[h], errors[h]+0
}'
Verificação de conhecimentos: inicializando o mínimo corretamente
Teste sua compreensão de uma armadilha comum na agregação com awk.
Recapitulação da lição: agregação com matrizes do awk
Você aprendeu os principais padrões para calcular agregações por grupo inteiramente dentro do awk:
- Contagem:
count[$key]++— incremente a cada linha e imprima emEND - Soma:
total[$key] += $N— acumule campos numéricos por grupo - Média: mantenha
count[]etotal[]e divida emEND - Mínimo/máximo: inicialize na primeira ocorrência usando
!(key in arr)e depois compare - Chaves compostas: concatene campos com um separador para fazer agrupamentos multidimensionais
- Resultados ordenados: canalize a impressão de
ENDdo awk porsortpara obter uma ordem determinística - Redefinição de seções: use
delete arrpara limpar o estado entre seções lógicas da entrada
Esses padrões permitem substituir consultas pesadas a bancos de dados ou várias passagens de canalização por uma única execução eficiente do awk — uma habilidade essencial para a engenharia de shell em ambientes de produção.
Perguntas Frequentes
A aula “Agregação com matrizes e agrupamento no awk” é grátis?
Sim — o texto completo de “Agregação com matrizes e agrupamento no awk” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Linux Command Line & Bash Scripting Mastery, atualize para CoddyKit PRO. O curso de Linux Command Line & Bash Scripting Mastery inclui 4 aulas no total.
O que vou aprender em “Agregação com matrizes e agrupamento no awk”?
Calcule somas, contagens e resumos por agrupamento usando matrizes associativas indexadas pelos valores dos campos. Você pratica Linux Command Line & Bash Scripting Mastery com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Linux Command Line & Bash Scripting Mastery?
Nenhuma experiência prévia é necessária. Linux Command Line & Bash Scripting Mastery no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.
Quanto tempo leva a aula “Agregação com matrizes e agrupamento no awk”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Linux Command Line & Bash Scripting Mastery?
Sim. Cada aula de Linux Command Line & Bash Scripting Mastery inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Registros, campos e separadores personalizados no awk
- Padrões, intervalos e blocos BEGIN/END
- Agregação com matrizes e agrupamento no awk
- Funções do awk, formatação com printf e geração de relatórios