awk: introdução
Esta aula introduz o awk, uma poderosa linguagem de processamento de texto no Linux. Você aprenderá sua estrutura básica (padrão {ação}), como acessar campos ($1, $2), configurar separadores de campos e usar o comando print para gerar saídas formatadas.
O awk é uma ferramenta de processamento de texto e extração de dados presente em praticamente todas as distribuições Linux. Diferente de ferramentas como grep (que filtra linhas) e sed (que edita linhas), o awk trata cada linha como um registro composto por campos, permitindo operações baseadas em padrões e ações sobre esses campos. É ideal para gerar relatórios, transformar dados tabulares e automatizar análises de logs.
Nesta aula, vamos nos concentrar nos conceitos fundamentais: a estrutura de um programa awk (padrão { ação }), como acessar campos individuais ($1, $2), como controlar o separador de campos (FS) e como usar o comando print para exibir resultados.
Estrutura (padrão { ação })
Um programa awk é composto por uma série de regras no formato padrão { ação }. O padrão é uma condição que, quando verdadeira para uma linha de entrada, faz com que a ação associada seja executada. Se o padrão for omitido, a ação é executada para todas as linhas. Se a ação for omitida, o padrão é usado como condição e a linha é impressa (equivalente a { print }).
Por exemplo, o comando a seguir imprime todas as linhas do arquivo dados.txt (ação print sem padrão):
awk '{ print }' dados.txt
Já o exemplo abaixo imprime apenas as linhas que contêm a palavra "erro":
awk '/erro/ { print }' dados.txt
O padrão pode ser uma expressão regular (entre barras), uma expressão relacional (como $1 > 100), ou uma combinação lógica. A ação pode conter múltiplos comandos separados por ponto e vírgula ou por quebras de linha entre chaves.
Campos ($1, $2)
O awk divide cada linha de entrada em campos baseados em um separador (por padrão, espaços em branco consecutivos ou tabulações). O primeiro campo é acessado por $1, o segundo por $2, e assim por diante. $0 representa a linha inteira.
Considere o arquivo alunos.txt com o seguinte conteúdo:
João 85
Maria 92
Pedro 78
Para imprimir apenas os nomes (primeiro campo):
awk '{ print $1 }' alunos.txt
Saída:
João
Maria
Pedro
Para imprimir nome e nota separados por hífen:
awk '{ print $1 " - " $2 }' alunos.txt
Saída:
João - 85
Maria - 92
Pedro - 78
Campos numéricos podem ser usados em operações aritméticas. Por exemplo, para calcular a média das notas:
awk '{ soma += $2 } END { print "Média: " soma/NR }' alunos.txt
O bloco END é executado após o processamento de todas as linhas. NR é uma variável interna que contém o número de registros (linhas) processados.
Separadores
O separador de campos padrão do awk é qualquer sequência de espaços e/ou tabulações. Para alterá-lo, usamos a opção -F ou a variável interna FS (Field Separator).
Suponha um arquivo dados.csv com campos separados por vírgula:
nome,idade,cidade
Ana,30,São Paulo
Carlos,25,Rio de Janeiro
Para imprimir o nome e a cidade:
awk -F ',' '{ print $1, $3 }' dados.csv
Ou equivalentemente, usando BEGIN para definir FS:
awk 'BEGIN { FS = "," } { print $1, $3 }' dados.csv
O bloco BEGIN é executado antes de ler a primeira linha. Também podemos usar expressões regulares como separador. Por exemplo, para separar por um ou mais dois-pontos:
awk -F ':+' '{ print $1 }' arquivo.txt
Além do FS, existe a variável OFS (Output Field Separator) que define o separador usado na saída do print (padrão é espaço). Para imprimir campos separados por vírgula:
awk 'BEGIN { OFS = "," } { print $1, $2 }' alunos.txt
Saída:
João,85
Maria,92
Pedro,78
O comando print é a principal forma de gerar saída no awk. Ele imprime seus argumentos separados pelo valor de OFS (padrão espaço) e termina com um caractere de nova linha (controlado por ORS, Output Record Separator).
Podemos imprimir strings literais, variáveis, campos e expressões. Exemplos:
# Imprime a linha inteira
awk '{ print $0 }' arquivo
# Imprime dois campos com um espaço entre eles (padrão)
awk '{ print $1, $2 }' arquivo
# Imprime com texto explicativo
awk '{ print "Nome: " $1 ", Nota: " $2 }' arquivo
# Imprime sem nova linha no final (usando printf)
awk '{ printf "%s\t%s\n", $1, $2 }' arquivo
O printf permite formatação mais controlada, similar à linguagem C. Por exemplo, para alinhar colunas:
awk '{ printf "%-10s %5d\n", $1, $2 }' alunos.txt
Saída:
João 85
Maria 92
Pedro 78
Note que print adiciona automaticamente uma nova linha; printf não. Use \n para quebra de linha em printf.
Referências
- GNU Awk User's Guide
- awk(1) - Linux man page
- AWK Tutorial - Tutorialspoint
- Getting Started with gawk
- Awk Introduction Tutorial – 7 Awk Print Examples
Exercícios
-
Crie um arquivo chamado
notas.txtcom o seguinte conteúdo (separado por espaços):
Ana 7.5 8.0 9.0
Carlos 6.0 7.5 8.5
Bruna 9.0 9.5 10.0
Escreva um comando awk que imprima o nome e a média aritmética das três notas (com duas casas decimais).✓ Resposta:awk '{ media = ($2+$3+$4)/3; printf "%s %.2f\n", $1, media }' notas.txt -
Dado o arquivo
pessoas.csvcom campos separados por ponto e vírgula:
João;35;Programador
Maria;28;Designer
Pedro;42;Gerente
Use awk para imprimir apenas o nome e a profissão, separados por " - ".✓ Resposta:awk -F ';' '{ print $1 " - " $3 }' pessoas.csv -
Explique a diferença entre
print $1, $2eprint $1 $2no awk.✓ Resposta:print $1, $2imprime os campos separados pelo separador de saída (OFS, padrão espaço). Jáprint $1 $2concatena os campos sem separador (a vírgula é omitida, então os campos são concatenados como strings). Por exemplo, se $1="João" e $2="85", o primeiro imprime "João 85" e o segundo imprime "João85". -
Escreva um comando awk que leia o arquivo
dados.txte imprima apenas as linhas cujo segundo campo seja maior que 50 (suponha que o segundo campo seja numérico).✓ Resposta:awk '$2 > 50' dados.txtOu explicitamente:
awk '$2 > 50 { print }' dados.txt -
Usando o arquivo
alunos.txtdo exemplo (João 85, Maria 92, Pedro 78), crie um comando awk que imprima o nome e a nota, mas com a nota formatada com 3 dígitos (ex: 085, 092, 078). Dica: useprintfcom formato%03d.✓ Resposta:awk '{ printf "%s %03d\n", $1, $2 }' alunos.txt