- O awk é uma ferramenta para tratamento de textos baseada em expressões regulares.
- O awk lê um script e o aplica na sua entrada.
- o script pode ser passado como o primeiro parâmetro entre ' '
- ou então através da opção -f nome_do_script
- Um script awk é formado basicamente por pares do tipo
- PADRÃO AÇÃO
- A entrada é quebrada em registros (normalmente linhas); NR é o número de registros
- Os registros são quebrados em campos (normalmente nos espaços em branco) que podem ser referenciados por $1, $2, ..., $n. $0 se refere ao registro todo. NF é o número de campos.
- Se se quer usar um outro separador de campos, basta usar a opção -F para determinar qual o novo separador.
- exemplo: -F; determina que ; é o novo separador de campos
- Nas expressões regulares do awk:
- ^ casa com o começo da string (p.ex., começo da linha)
- $ casa com o fim da string ((p.ex., fim da linha)
- \ é o caractere de escape que pode ser usado para remover o significado especial de um caractere
- . casa com qualquer caractere, inclusive o newline
- [xyz] casa com 1 caractere do conjunto xyz (onde xyz é apenas um exemplo)
- [^xyz] casa com 1 caractere qualquer que não esteja no conjunto xyz
- | para indicar alternativas (ou)
- * significa a expressão anterior repetida 0 ou mais vezes
- + significa a expressão anterior repetida 1 ou mais vezes
- o padrão BEGIN casa com o início do arquivo e END com o final
- A utilização do awk pode economizar um tempo enorme quando se tem tarefas repetitivas e longas para executar.
- Este comando seguinte, faz o que???
ls junk* | awk '{print "mv "$0" ../lixo/"$0".lix"}' | csh- se eu tivesse milhares de arquivos, fazer isso na mão demoraria horas; criando um script, demoraria alguns minutos; com o awk demora alguns poucos segundos.
- As variáveis não são declaradas. Elas passam a existir na primeira vez em que são usadas.
- Não existe tipo de variável. Cada variável pode conter qualquer tipo.
- Além das variáveis normais, podem ser utilizados vetores. Os vetores no entanto têm uma característica interessante: seus índices são cadeias de caracteres (vetores associativos). Veja o exemplo abaixo.
- Exemplo:
- Um contador de ocorrências de palavras, é um dos exemplos mais comuns em AWK.
- A variável especial NF contém o número de campos no registro corrente:
# frequência de palavras
{
for (i = 1; i <= NF; i++)
freq[$i]++
}END {
for (word in freq)
printf "%s\t%d\n", word, freq[word]
}- outro exemplo com vetores: (o que ele faz???)
{
if ($1 > max)
max = $1
arr[$1] = $0
}
END {
for (x = 1; x <= max; x++)
if (x in arr)
print arr[x]
}- o que faz o programa a seguir???
{ s += $1 }
END { print "sum is", s, " average is", s/NR }'- o que faz o comando awk -F: '{ print $1 }' /etc/passwd ???
- /XXXX/ indica que XXXX é o padrão a ser buscado, ou seja, apenas linhas que casam com aquele padrão vão ser consideradas naquela ação.
- Vejamos alguns exemplos mais:
- awk '/^[AEIOUaeiou]/' imprime todas as linhas que começam com uma vogal. ^significa o começo da linha.
- awk '$2 > $1' linhas cuja segunda palavra é maior (numérica ou lexicograficamente) do que a primeira. A comparação será numérica se ambas palavras tiverem representação numérica.
- awk '/^[a-zA-Z]+ +[0-9]+ +x +[0-9]+ +[a-zA-Z]+/ && $2>$4':
Resultados de jogos onde o primeiro time venceu (o nome do time não pode ter espaços).
- awk '/^[0-9]/ || $2 > 3$' começando com dígito ou com o segundo campo maior do que o terceiro.
- awk '$1 ~ /Janeiro/' linhas cujo primeiro campo casa com a expressão regular Janeiro.
- awk '$1 !~ /Janeiro/' linhas cujo primeiro campo não casa a expressão regular Janeiro.
- O operador ~ é chamado de "match" e diz se uma expressão casa com um determinado padrão especificado através de uma expressão regular. Os operadores ~ e !~ podem ser utilizados como no exemplo acima ou dentro de comandos if, while, e for.
- Últimos exemplos interessantes:
- ls -lg | awk '$6 == "Nov" { sum += $5 }
END { print sum }'
- Onde a saída do comando ls -lg é algo como:
-rw-r--r-- 1 arnold user 1933 Nov 7 13:05 Makefile
-rw-r--r-- 1 arnold user 10809 Nov 7 13:03 gawk.h
-rw-r--r-- 1 arnold user 983 Apr 13 12:14 gawk.tab.h
-rw-r--r-- 1 arnold user 31869 Jun 15 12:20 gawk.y
-rw-r--r-- 1 arnold user 22414 Nov 7 13:03 gawk1.c
-rw-r--r-- 1 arnold user 37455 Nov 7 13:03 gawk2.c
-rw-r--r-- 1 arnold user 27511 Dec 9 13:07 gawk3.c
-rw-r--r-- 1 arnold user 7989 Nov 7 13:03 gawk4.c
- awk '{$2 = ""; print}'
- BEGIN{
for (i=175;i>133;i--){
printf "lprm -Pinga %d\n", i
} exit
}- Exercício:
- escreva um programa em awk que calcule a soma e a média dos comprimentos das linhas que começam com um número.
- dica: o comprimento da linha é dado pela variável length
- Um último exemplo interessante de como gerenciar uma coleção de moedas
- Mais informações no manual do GNU awk