Programação em AWK
Blau Araujo
Conteúdo das aulas
Playlist do curso
- Download da playlist
Depende do programa
yt-dlp
:yt-dlp https://www.youtube.com/playlist?list=PLXoSGejyuQGroZqA8T7P8_T-qR-islONm
1. A linguagem
Características | |
---|---|
Criadores | Alfred (A)ho, Peter (W)einberger e Brian (K)ernighan. |
Motivação | Escrever programas simples e curtos para a linha de comandos. |
Lançamento | 1977 (Unix V7) |
Sintaxe | Inspirada na linguagem C. |
Execução | Linguagem interpretada. |
Filtro | Funciona como um utilitário que processa fluxos de texto. |
Propósito | Tarefas de processamento e manipulação de dados em texto. |
Secundariamente | Processamento de fluxos de texto em geral. |
Binário atual | nawk (Software Livre, mantido por Brian Kernighan) |
1.1 - Implementações mais importantes
- Original
- Lançada em 1977 com o Unix V7.
- NAWK
Atualização do AWK original iniciada em 1985 e descrita no livro The AWK Programming Language, publicado em 1988. Em 1996 foi tornada um Software Livre e é mantida até hoje por Brian Kernighan.
Pacote Debian:
original-awk
- GAWK
Implementação livre para o Projeto GNU. Descrição publicada online e no livro Effective AWK Programming, de Arnold Robbins.
Pacote Debian:
gawk
- MAWK
Implementação feita por Mike Brennan com o propósito de ser extremamente rápida. É a implementação instalada por padrão no Debian GNU/Linux.
Pacote Debian:
mawk
1.2 - Estrutura básica dos programas
Por padrão, os programas em awk
são escritos para lerem dados recebidos pela
entrada padrão ou pela leitura de arquivos cujos nomes forem passados como
argumentos na invocação do interpretador. Cada linha de dados lida é tratada
como um registro e só será processada se houver algum casamento entre seu
conteúdo e uma das regras associadas a um bloco de ações.
Portanto, um código em
awk
sempre será escrito em pares de regras e ações.
Bloco de ações
O código a ser executado no casamento de uma regra. Havendo uma regra
definida, a ação padrão por omissão é imprimir o registro lido (equivale à
ação { print }
).
Regras
Expressões que determinam se, ou quando, o bloco de ações será executado.
/REGEX/
- Uma expressão regular descrevendo o padrão de texto buscado nas linhas recebidas pela entrada padrão (registros).
- Expressão
- Qualquer expressão de comparação, lógica ou aritmética que resulte em zero (falso) ou diferente de zero (verdadeiro).
- regra-inicial, regra-final
- Um par de expressões, separadas por vírgula, especificando uma faixa de registros.
- BEGIN/END
- Regras especiais para definir ações que devem ser executadas no
antes (
BEGIN
) e depois (END
) da leitura de todos os registros. Um código contendo apenas a regraBEGIN
pode ser executado sem a leitura de dados na entrada padrão (arquivos, pipes, etc). - BEGINFILE/ENDFILE
- Regras especiais para definir as ações que devem ser
executadas antes (
BEGINFILE
) e depois (ENDFILE
) da leitura de cada arquivo. - Regra vazia (sem regra)
- A regra vazia casa com todos os registros lidos.
1.3 - Execução dos programas
Na linha de comandos
Na linha de comandos, o código do programa é um argumento da invocação do awk
e, geralmente, é escrito entre aspas simples para evitar que o shell expanda seu
conteúdo.
awk [OPÇÕES] 'regra { ações } regra {ações} ...' [ARQUIVOS]
Em arquivos de código
Os programas em awk
também podem ser escritos em arquivos:
regra { ações } regra { ações } ...
Arquivos de programas em awk
podem ser executados como argumentos da invocação
explícita do interpretador ou pela invocação implícita em uma hashbang, desde
que o arquivo tenha permissão de execução.
- Invocação explícita
awk -f programa.awk [ARQUIVOS]
- Hashbang para o interpretador padrão do sistema
#!/usr/bin/env -S awk -f
- Hashbang para um interpretador específico
#!/bin/gawk -f
- Execução de arquivos executáveis
./programa.awk [ARQUIVOS]
1.4 - Primeiro contato
Salve, simpatia!
- Execução de código independente da passagem de dados na entrada ou do nome de um arquivo
awk 'BEGIN { print "Salve, simpatia!" }'
Saída:
Salve, simpatia!
- Passando uma linha de texto pela entrada padrão (regra "vazia")
echo 'Salve, simpatia!' | awk '{print "O registo " NR " contém o texto: " $0}'
Saída:
O registo 1 contém o texto: Salve, simpatia!
- Passando uma linha de texto pela entrada padrão (regra sem ação)
echo 'Salve, simpatia!' | awk '1'
Saída:
Salve, simpatia!
- Isso não significa que podemos omitir regras e ações ao mesmo tempo
echo 'Salve, simpatia!' | awk ''; echo $?
Saída:
0
Processamento de dados em tabelas
Arquivo exemplos/compras1.txt:
Item Preço Qtd Unidade Banana 5,00 3 1kg Arroz 15,00 5 2kg Feijão 12,00 10 1kg Leite 4,00 4 1l
- Imprimir apenas um registro
awk 'NR == 2' exemplos/compras1.tab
Saída:
Banana 5,00 3 1kg
- Imprimir tudo a partir do registro 2
awk 'NR > 1' exemplos/compras1.tab
Saída:
Banana 5,00 3 1kg Arroz 15,00 5 2kg Feijão 12,00 10 1kg Leite 4,00 4 1l
- Total gasto com cada item
awk 'NR > 1 {print $1 ": R$" $2 * $3}' exemplos/compras1.tab
Saída:
Banana: R$15 Arroz: R$75 Feijão: R$120 Leite: R$16
- Total de unidades a comprar (com saídas formatadas)
awk 'NR > 1 { printf "%6-s: %d",$1,$3 * $4; gsub(/[0-9]/,"",$4); print $4}' exemplos/compras1.tab
Saída:
Banana: 3kg Arroz : 10kg Feijão: 10kg Leite : 4l
- Valor total da compra
awk 'NR > 1 {itens++; total+=$2*$3} END {print "Valor total: R$" total}' exemplos/compras1.tab
Saída:
Valor total: 226
2. AWK em scripts
Nós podemos trabalhar com o AWK em scripts de duas formas básicas:
- Scripts totalmente em AWK
Todo o código do script é escrito na linguagem em AWK e eventuais comandos do shell são executados com pipes ou pela função interna
system()
.#!/bin/gawk -f BEGIN { print "Salve, simpatia!" }
- Scripts em shell com invocações do AWK
A forma mais comum e flexível de criar scripts com o AWK, porque alia o poder dos recursos do shell com as funcionalidades da linguagem AWK.
#!/bin/bash awk 'BEGIN {print "Salve, simpatia!}'
Passagem de arquivos para scripts totalmente em AWK
Em princípio todos os argumentos na invocação de um script em AWK são interpretados como nomes de arquivos.
Arquivo nomes.txt:
Aho, Alfred Weinberger, Peter Kernighan, Brian
Script salve.awk:
#!/bin/gawk -f { print "Salve, " $2 "!" }
Executando o script com um nome de arquivo como argumento:
:~$ ./salve.awk nomes.txt
Saída:
Salve, Alfred! Salve, Peter! Salve, Brian!
É possível fazer com que o código interprete a passagem de qualquer palavra na invocação de scripts em AWK como argumentos genéricos (vetores
ARGV
eARGC
), mas este é um assunto para mais adiante.
Passagem de variáveis do shell para scripts em AWK
- Opção
-v
- Com a opção
-v NOME=VALOR
, nós podemos passar a variávelNOME
para scripts em AWK:
:~$ awk -v usr=$USER 'BEGIN {print "O seu nome de usuário é " usr "!"}' O seu nome de usuário é blau!
Também funciona com scripts (username.awk):
#!/bin/gawk -f BEGIN { print "Seu nome de usuário é " usr "!" }
Executando:
:~$ ./username.awk -v usr=$USER Seu nome de usuário é blau!
- Variáveis diretas
- Variáveis também podem ser passadas do shell para o script em AWK por atribuições feitas diretamente antes de nomes de arquivos:
:~$ 'BEGIN {print var}' var=banana :~$ awk 'BEGINFILE {print var}' var=banana nomes.txt banana
Como essas atribuições precisam ser feitas antes de nomes de arquivos, elas só poderão ser avaliadas em regras e ações relacionadas com arquivos!
- Exportação de variáveis
- Variáveis também podem ser passadas através do mecanismo da exportação. Para
isso, o script deve avaliar o nome da variável exportada como chave do vetor
associativo
ENVIRON
:
Script environ.awk:
#!/bin/gawk -f BEGIN { print "O valor da variável exportada \042fruta\042 é \042" ENVIRON["fruta"] "\042" }
Executando:
:~$ fruta=pitanga ./environ.awk O valor da variável exportada "fruta" é "pitanga"
Apoie o meu trabalho
- PIX: pix@blauaraujo.com
- Apoia.se
- Curso: Shell Script Descomplicado
- Meus livros
- Camisetas