sexta-feira, 4 de maio de 2012

Exibindo determinadas colunas com o awk

O programa awk é um editor de fluxo de texto. Sua função básica é procurar, em arquivos ou fluxo de dados, linhas ou textos que contenham um ou mais padrões. Quando a linha casa com um dos padrões, uma ação pode ser executada na respectiva linha.

Nas distribuições de Linux é comum encontrar o gawk, uma variante GNU com algumas extensões. O gawk possui todas as funcionalidades do awk original do UNIX. Neste artigo o programa será referenciado simplesmente como awk, entretanto usando como base o programa gawk.

O awk possui uma linguagem de programação própria, usando o tipo de dado string, arrays associativos e expressões regulares. Este artigo não abordará a linguagem toda mas apenas uma ação de impressão na saída padrão, a instrução print.

A sintaxe padrão do programa awk é:

gawk [opções] 'programa' arquivo

A única opção utilizada neste artigo é a -F, a qual define um ou mais caracteres como separadores de campo, ou delimitadores de campo. Por padrão o awk separa as palavras (ou campos) da linha delimitando-as pelos espaços vazios entre elas, incluindo qualquer caractere de espaço ou tab. Semelhante a arquivos CSV, onde os valores são separados por vírgula. Com a opção -F é possível especificar um caractere que será utilizado como delimitador, por exemplo "-F ,". Cada campo da linha será tratado como uma coluna vertical, como será visto mais adiante.

O argumento 'programa' define o processamento executado pelo awk. Pode ser um programa completo com uma sequência de instruções com condição-ação ou um simples comando, como será tratado aqui, o comando print. É importante proteger o código do programa com aspas, assim o shell não interpretará quaisquer caracteres especiais contidos no programa. Fazendo com que o shell trate todo o programa como um único argumento para o awk. Na sintaxe da linha de comando do awk, a instrução de ação deve ficar entre chaves, { e }.

A instrução de entrada/saída "print" é usada para realizar a saída de texto, na tela ou redireção a um arquivo, como em outras linguagens. Faz a impressão do resultado do programa. Como não usaremos uma condição, a instrução print será executada em cada linha da entrada.

Além da instrução print, na ação podemos incluir operadores. O operador para determinar quais colunas serão impressas é o $, na sintaxe $n. O número n indica a coluna, ou o campo na linha. Também é possível incluir sequências de caracteres, entre aspas, e alguns caracteres de escape, como \n (nova linha), \t (tab horizontal) e \ddd (caractere ASCII representado pelos três dígitos).

Vamos aos exemplos. A saída do comando "ls -l" retorna uma série de dados tabulados onde na primeira coluna temos as permissões, na segunda o número de ligações, na terceira o proprietário etc., em um total de "nove" colunas:

$ ls -l
drwxr-xr-x.  2 daniel daniel 4096 Mai  2 08:09 Desktop
drwxr-xr-x. 22 daniel daniel 4096 Mai  1 11:03 Documentos
drwxr-xr-x.  9 daniel daniel 4096 Mai  3 23:05 Downloads
drwxr-xr-x.  4 daniel daniel 4096 Abr 19 13:19 Imagens
drwxr-xr-x.  2 daniel daniel 4096 Jan  4 16:52 Músicas
drwxr-xr-x.  5 daniel daniel 4096 Mai  1 11:10 Vídeos

    $1      $2   $3     $4    $5  $6  $7  $8     $9

Para ser exibido em tela apenas a primeira coluna, com as permissões, e a nona coluna, com os nomes dos arquivos e diretórios, podemos usar a seguinte linha de comando:

$ ls -l | awk '{print $1 "\t" $9}'

A saída será:

drwxr-xr-x.     Desktop
drwxr-xr-x.     Documentos
drwxr-xr-x.     Downloads
drwxr-xr-x.     Imagens
drwxr-xr-x.     Músicas
drwxr-xr-x.     Vídeos

Obs.: O comando ls talvez tenha opções que façam esta filtragem, não vem ao caso. Se o nome do arquivo ou diretório conter espaço, somente a primeira palavra será exibida, a "nona" coluna.

Também podemos dar como entrada um arquivo. Se neste arquivo os campos estiverem separados por dois pontos, por exemplo no arquivo /etc/passwd, poderíamos usar a seguinte linha de comando para exibir somente o nome do usuário e o caminho do diretório home:

# awk -F : '{print "Usuário: " $1 "\tDiretório: " $6}' /etc/passwd

O awk é muito útil para filtragem de textos e formatação durante um processamento textual em um shell script, juntamente com o programa sed. Por exemplo, esta linha em um script, alimentaria a variável CONT com o número de linhas do arquivo texto:

CONT=`wc -l artigo.txt | awk '{print $1}'`

Consulte a página manual do awk para conhecer tudo que este interessante programa é capaz de fazer (man gawk).

Nenhum comentário:

Postar um comentário