Nesse artigo vamos conhecer um pouco sobre uma poderosa ferramenta do Linux para trabalharmos com arquivos de texto, o awk. Geralmente utilizamos o awk nas situações onde é necessário extrair algum conteúdo de um arquivo texto e montar relatórios formatados.
Uma Breve Introdução
Na verdade o awk não é um simples comando, ele é uma linguagem de programação criada em 1977 nos laboratórios da Bell Labs. O nome awk é uma abreviatura dos seus criadores Alfred Aho, Peter J. Weinberger e Brian Kernighan – (Aho, Weinberger e Kernighan).
Resumidamente, podemos dizer que seu príncipio se baseia em procurar em um ou mais arquivos por linhas que contenham um determinado padrão e, quando encontrar, executar uma determinada ação. Por padrão, o awk lê a partir de um arquivo e mostra o resultado na saída padrão.
O awk é muito utilizado em shell script e sua sintaxe básica é:
awk ‘
/padrão1/ {ação1}
/padrão2/ {ação2}
‘ arquivo1 arquivo2 arquivo3onde os padrões são expressões regulares.
Como podemos observar acima o awk irá procurar em três arquivos (arquivo1, arquivo2, arquivo3) pelos padrões especificados (padrão1 e padrão2). Quando achar o padrão1 irá executar a ação1 e quando achar o padrão2 irá executar ação2.
Como o awk Funciona
Vamos utilizar o exemplo da sintaxe mostrada anteriormente e enumerar algumas regras importantes sobre o awk.
1. O awk lê nos arquivos informados uma linha por vez.
2. Para cada linha do(s) arquivo(s), ele procurar pelos padrões informados e quando os encontra executa a ação específica.
3. Se nenhum padrão for encontrado, o awk não executará nenhuma ação.
4. Na sintaxe mostrada, tanto o padrão quanto a ação são opcionais. Mas não ambos, ou seja, você pode informar somente o campo “padrão” ou somente o campo “ação”, mas um dos dois deve estar presente.
5. Caso não seja especificado um padrão para busca, então o awk irá realizar a ação informada em todas as linhas do(s) arquivo(s)
6. Caso não seja especificado nenhuma ação, o awk irá executar sua ação padrão que o print, ou seja, irá imprimir o resultado em sua saída padrão.
7. O formato {}, abrir e fechar as chaves sem informar nenhuma ação, não tem nenhum efeito. Não será executada a ação padrão (print).
8. Caso seja necessário, podemos informar mais de uma ação. Para isso, devemos separá-las por “ponto e vírgula”.
Vamos em seguida ver alguns exemplos de uso do awk.
Exempos de uso do awk
Antes de mais nada, vamos considerar os exemplos com base no arquivo texto abaixo. Esse arquivo é uma relação de compras (hipotética) com os seguintes campos:
id,nome,sobrenome,produto,valor,data
Segue o conteúdo do arquivo utilizado como exemplo:
1,marcio,da silva,dk9102,200.00,2013-10-01
2,alex,ribeiro,qr8790,110.00,2013-10-01
3,maria,clara,dk9102,200.00,2013-10-02
4,roberto,albieri,rt6543,50.00,2013-10-02
5,franciso,prado,qr8790,110.00,2013-100-02
6,adalberto,mathias,qr8790,110.00,2013-10-03
7,eduardo,figuereido,dk9102,200.00,2013-10-03
8,brian,johnson,rt6543,50.00,2013-10-03
9,jason,killer,rt6543,50.00,2013-10-03
10,alex,ribeiro,dk9102,200.00,2013-10-03
Exemplo 01: Imprimir as linhas que contenham um determinado padrão
Por exemplo, suponha que precisamos exibir a relação de compras do produto com o código dk9102.
$ awk ‘/dk9102/‘ compras.csv
1,marcio,da silva,dk9102,200.00,2013-10-01
3,maria,clara,dk9102,200.00,2013-10-02
7,alex,ribeiro,dk9102,200.00,2013-10-01
10,jason,killer,dk9102,200.00,2013-10-03
No exemplo, ao encontrar o padrão especificado o awk irá imprimir o conteúdo da linha.
Exemplo 02: Imprimir somente campos específicos
Agora vamos utilizar o awk para exibir as compras do produtos dk9102, mas queremos exibir somente o produto, o nome do comprador e a data da compra, nessa ordem.
O awk utiliza variáveis internas para guardar os valores de campo. Por padrão, o awk utiliza o “espaço em branco ou tabs” como separador de campos. O valor do primeiro campo é guardado na variável $1, o segundo na $2 e assim por diante. Quando o seu arquivo possui outro caractere como separador de campo, a opção -F deve ser utilizada para informar o caractere a ser considerado como separador de campos. Em nosso exemplo, o separador de campos é a vírgula, logo, devemos utilizar a opção -F “,”.
$ awk -F “,” ‘/dk9102/ {print $4,$2,$6;}’ compras.csv
dk9102 marcio 2013-10-01
dk9102 maria 2013-10-02
dk9102 alex 2013-10-01
dk9102 jason 2013-10-03
Vamos explicar o comando…
$ awk -F “,” ‘/dk9102/ {print $4,$2,$6;}’ compras.csv
-F “,” –> diz ao awk para considerar a vírgula como separador de campos
/dk9102/ –> padrão a ser procurado
{print $4,$2$,6} –> imprimir o quarto, segundo e sexto campo (produto,nome,data)
Agora perceba também que na saída do comando os campos foram separados por espaços.
dk9102 marcio 2013-10-01
dk9102 maria 2013-10-02
dk9102 alex 2013-10-01
dk9102 jason 2013-10-03
Para alterar o separador na saída devemos utilizar a instrução OFS (Output Field Separator) como sendo uma ação a ser executada. Acompanhe abaixo, onde iremos colocar a saída do comando separadas por um tab (\t)
$ awk -F “,” ‘/dk9102/ {OFS=”\t”;print $4,$2,$6;}’ compras.csv
dk9102 marcio 2013-10-01
dk9102 maria 2013-10-02
dk9102 alex 2013-10-01
dk9102 jason 2013-10-03
Exemplo 03: Ação Inicial e Ação Final
O awk possui dois padrões específicos, chamados BEGIN e END, que são utilizados para informar ações no início e no final do processamento. Por exemplo, o BEGIN diz ao awk o que deve ser feito antes que ele inicie a leitura das linhas do arquivo, já o END indica o que se deve fazer no final da leitura. O BEGIN e o END são muito utilizado para formamos relatórios com formatação específica.
Por exemplo, vamos tornar o exemplo anterior mais fácil de se ler, construindo um relatório com uma tabela, onde na primeira linha colocaremos os nomes de cada campo e no final da tabela iremos colocar a data do relatório.
$ awk -F “,” ‘
BEGIN {
print “\n”;
print “Relatorio de Compras – dk9102”;
print “—————————————–“;
print “Produto\t\tCliente\t\tData”;
print “—————————————–“;}
/dk9102/ {OFS=”\t\t”;print $4,$2,$6;}
END {
print “—————————————–“;}
‘ compras.csv
Relatorio de Compras – dk9102
—————————————–
Produto Cliente Data
—————————————–
dk9102 marcio 2013-10-01
dk9102 maria 2013-10-02
dk9102 alex 2013-10-01
dk9102 jason 2013-10-03
—————————————–
Exemplo 04: Criando Variáveis
Com o awk podemos criar nossas próprias variáveis, bastando definir as variáveis que queremos. Vamos incrementar nosso exemplo anterior mostrando no final do relatório o somatório do total vendido. O valor do produto está no quinto campo ($5), logo basta utilizá-lo para somar o total vendido.
awk -F “,” ‘
BEGIN {
total=0;
print “\n”;
print “Relatorio de Compras – dk9102”;
print “—————————————–“;
print “Produto\t\tCliente\t\tData”;
print “—————————————–“;}
/dk9102/ {OFS=”\t\t”;print $4,$2,$6;total+=$5}
END {
print “—————————————–“;
print “total = R$” total;}
‘ compras.csvRelatorio de Compras – dk9102
—————————————–
Produto Cliente Data
—————————————–
dk9102 marcio 2013-10-01
dk9102 maria 2013-10-02
dk9102 alex 2013-10-01
dk9102 jason 2013-10-03
—————————————–
total = R$800
Perceba que na seção BEGIN definimos uma variável total como valor zero (total=0). Já na execução da nossa ação inserimos a ação total+=$5, somando o valor do produto em cada linha encontrada. Por fim, na seção END mandamos exibir o valor da variável total.
Exemplo 05: Lendo as Instruções de um Arquivo
Até agora você pode estar pensando “Entrar com todos essas instruções na linha de comando é muito complicado”…No entanto, também podemos fazer com que o awk leia as instruções de um arquivo. Isso fazemos com a opção -f seguido do nome do arquivo onde estão as instruções.
$awk –f arquivo-com-instrucoes arquivo-de-entrada
Então imagine o seguinte, vamos pegar as instruções utilizadas anteriormente e colocar em um arquivo chamado “dk9102.awk”. Acompanhe abaixo a saída do comando cat mostrando o conteúdo do arquivo:
$ cat dk9102.awk
BEGIN {
total=0;
print “\n”;
print “Relatorio de Compras – dk9102”;
print “—————————————–“;
print “Produto\t\tCliente\t\tData”;
print “—————————————–“;
}
/dk9102/ {
OFS=”\t\t”;
print $4,$2,$6;
total+=$5;
}
END {
print “—————————————–“;
print “total = R$” total;
}
Agora, basta utilizarmos a opção -f para informar ao awk de qual arquivo ele deverá ler as instruções.
$ awk -F “,” -f dk9102.awk compras.csv
Relatorio de Compras – dk9102
—————————————–
Produto Cliente Data
—————————————–
dk9102 marcio 2013-10-01
dk9102 maria 2013-10-02
dk9102 alex 2013-10-01
dk9102 jason 2013-10-03
—————————————–
total = R$800
Bom pessoal, por hora é isso aí. Mostramos aqui apenas alguns exemplos do uso do awk com o objetivo de incentivar a sua curiosidade em estudar essa poderosa ferramenta disponível no Linux. As possibilidades de uso são incríveis e o domínio dessa ferramenta pode auxiliar em muito a execução de extração de dados em arquivos texto. E se quiserem ler mais sobre outros exemplos de uso do awk aqui no blog da DlteC não deixem de comentar o artigo…
4 Responses
Opa qual linux foi usado para os testes Alexei, usei o ubuntu 14.10 da alguns erros de syntaxe: /usr/bin/awk -F “,” -f dk9102.awk compras.csv
awk: 1: unexpected character ‘.’
awk: 1: unexpected character 0xe2
awk: 2: unexpected character 0xe2
awk: 3: unexpected character 0xe2
awk: 3: unexpected character 0xe2
Você tem que trocar esses caracteres que estão em html para o ‘ e ” normais
como eu posso resolver esta questao (Desenvolva um script em AWK que tenha por finalidade analisar arquivos KML que apresentem um polígono, como o do modelo, que processem tais arquivos informando o nome do polígono (localizado entre as tags e ) e o centro das coordenadas (localizadas entre as tags e ))
No exemplo 2 tem um $ fora de lugar na parte amarela: {print $4,$2$,6}