Olá pessoal,
vamos lá com um primeiro post técnico do blog!
Resolvi começar com AWK por julga-lo útil, interessante e pratico. Quantos de vocês já tiveram que interpretar (vulgo “parsear”) um arquivo com algum formato fixo, aonde os campos são definidos por separados como: ‘,’, ‘|’, ‘.’, ‘/’, etc… ?
Acho que quase todo mundo não?
Então, o AWK é uma ferramenta bem pratica e útil pra esses casos!!! Sabe-lo usar, pelo menos de forma básica, pode te ajudar em muitas situações do dia-a-dia de um linux-user.
Para quem não conseguiu imaginar uma situação de uso real pra ele vou citar como exemplo um arquivo csv com todos os seus contatos do gmail , e por algum motivo, vamos julgar que você quer pegar este arquivo, interpretar ele de acordo com seu cabeçalho e enviar um email para cada um de seus contatos…como você faria?
Dadas as situações acima, vamos deixar claro algumas coisas:
- O que é o AWK?
Se consultarmos o manual do sistema (man AWK, guarde esse comando..ele salva vidas!) teremos a melhor definição possível do que é esse aplicativo:
“pattern scanning and processing language”
Ou seja..é basicamente um aplicativo feito para varrer o, buscar padrões e processar essas informações do jeito desejado.
- Sintaxe básica:
O awk possui uma extensa gama de opções, comandos e parâmetros, mas a mais usada(e mais simples) se refere a simplesmente, para cada linha do arquivo de entrada imprimir a coluna desejada dado o separador entre essas colunas, por exemplo:
-Vamos usar de exemplo de entrada para o awk o header do arquivo csv da lista de contatos do gmail, usaremos o comando head para pegar somente esta linha:
marco@psychokiller:~/hd/Arquivos/Projetos/Controle$ head -1 mailings/google.csv
Name,Given Name,Additional Name,Family Name,Yomi Name,Given Name Yomi,Additional Name Yomi,Family Name Yomi,Name Prefix,Name Suffix,Initials,Nickname,Short Name,Maiden Name,Birthday,Gender,Location,Billing Information,Directory Server,Mileage,Occupation,Hobby,Sensitivity,Priority,Subject,Notes,Group Membership,E-mail 1 – Type,E-mail 1 – Value,E-mail 2 – Type,E-mail 2 – Value
como podemos perceber, o csv gerado pelo google contém um número elevado de campos (e mais pra frente vamos aprender a conta-los via AWK 😉 ) e como era de se esperar o separador dos campos é o caracter ‘,’.
-Imprimindo um dos campos na tela:
Agora vamos imprimir aleatóriamente qualquer um desses campos na tela…por exemplo o campo 12. Observem a linha de comando abaixo, logo após ela está a explicação de cada parte do comando.
marco@psychokiller:~/hd/Arquivos/Projetos/Controle$ head -1 mailings/google.csv | awk -F’,’ ‘{print$12}’
Nickname
bom….agora vamos por partes….aqui a brincadeira começa a ficar bem interessante. Pra quem não é muito familiarizado com Linux deve estar pensando: “Mas que diabos ele fez?”!
A primeira parte simplesmente retorna a primeira linha do arquivo (no caso do formato csv é sempre a descrição dos campos do arquivo): head -1 <arquivo>, o argumento após o – é o número de linhas que quero retornar tomando por base o ínicio do arquivo. O comando head -n <arquivo> retornaria as n primeiras linhas do arquivo.
O caracter ‘|’ (pipe) indica a ligação da saída padrão do primeiro comando na entrada padrão do segundo comando. É fácil entender ele…basta pensar no sentido literal da palavra (pipe=cano); ligamos um cano da saída de um comando para a entrada de outro, ou seja, a saída do primeiro comando será interpretada como a entrada do segundo comando. Não é lindo isso? 😀
agora vamos a parte que realmente interessa aqui…o AWK!
Para essa formatação do comando temos:
awk -F'<separador de campos>’ ‘{<bloco de ação>}’
no caso nosso separador é o caracter ‘,’…então devemos fazer o set up do comando para ‘,’..por isso -F’,’. Por padrão, se não específicado, o separador de campos é ‘ ‘(isso mesmo um espaço em branco), portanto tome muito cuidado com essa variável…um exemplo de um erro causado por não ter feito o set up correto do separador no nosso exemplo seria:
marco@psychokiller:~/hd/Arquivos/Projetos/Controle$ head -1 mailings/google.csv | awk ‘{print$12}’
Prefix,Name
totalmente incorreto não?
Internamente esse separador fica em uma variável chamada ‘FS’, que vou abordar no próximo post para não deixar este longo demais.
Dentro do bloco de comandos, o trecho compreendido entre ‘{}’, a sintaxe é quase igual a sintaxe do C, o que facilita um pouco o aprendizado. No nosso caso usamos o comando print, que como o próprio nome diz, imprime iinformações na tela. Cada coluna é armazenada dentro da variável $<numero da coluna>, sendo assim: $1 = primeira coluna; $2 = segunda coluna; … ; $n = enésima coluna.
(IMPORTANTE: O numero de colunas é definido, novamente, pelo separador de campos passado no argumento -F)
Resumindo essa parte:
1)Filtramos o arquivo para obter somente a primeira linha;
2)Separamos essa linha em colunas delimitadas pelo caracter ‘,’
3)Imprimimos a 12ª coluna
Obs.: Podemos obter o numero de colunas de um arquivo através da variável NF(Number of fields) como nesse exemplo:
marco@psychokiller:~/hd/Arquivos/Projetos/Controle$ head -1 mailings/google.csv | awk -F’,’ ‘{print NF}’
31
marco@psychokiller:~/hd/Arquivos/Projetos/Controle$
Obs.: Você pode imprimir os dados que quiser, bem como quantas colunas quiser, assim:
marco@psychokiller:~/hd/Arquivos/Projetos/Controle$ head -1 mailings/google.csv | awk -F’,’ ‘{print “Imprimindo as primeira e a ultima coluna:” $1,FS, $NF}’
Imprimindo as primeira e a ultima coluna:��Name , E-mail 2 – Value
marco@psychokiller:~/hd/Arquivos/Projetos/Controle$
Acho que pra um primeiro post já é o suficiente, no próximo post falarei um pouco mais sobre o awk, mas com uma abordagem mais avançada, faremos scripts mais complexos…usando expressões regulares e estruturas de controle de fluxo.
Qualquer duvida sintam-se livres para me perguntar!
Deixem suas opinioes nos comentários!
Abs a todos…até a próxima!