Um guia para a escrita awk intermédia

Este artigo explora as capacidades do awk, que são mais fáceis de usar agora que sabe como estruturar o seu comando num script executável.

Operadores lógicos e condicionais

P>Pode usar os operadores lógicos e (escrito &&) e ou (escrito |||) para adicionar especificidade aos seus condicionais.

Por exemplo, para seleccionar e imprimir apenas registos com a string “roxo” na segunda coluna e um valor inferior a 5 na terceira coluna:

$2 == "purple" && $3 < 5 {print $1}

Se um registo tiver “roxo” na segunda coluna mas um valor superior ou igual a 5 na terceira coluna, então não é seleccionado. Da mesma forma, se um registo corresponder aos requisitos da coluna três mas não tiver “roxo” na coluna dois, também não é seleccionado.

Diga que deseja seleccionar cada registo no seu ficheiro onde o valor é maior ou igual a oito e imprima um registo correspondente com dois asteriscos (**). Também quer marcar cada registo com um valor entre cinco (inclusive) e oito com apenas um asterisco (*). Há algumas maneiras de o fazer, e uma maneira é usar o comando seguinte para instruir o awk que depois de tomar uma acção, deve parar de digitalizar e prosseguir para o próximo registo.

Aqui está um exemplo:

NR == 1 {
print $0;
next;
}
$3 >= 8 {
printf "%s\t%s\n", $0, "**";
next;
}
$3 >= 5 {
printf "%s\t%s\n", $0, "*";
next;
}
$3 < 5 {
print $0;
}

comando BEGIN

O comando BEGIN permite-lhe imprimir e definir variáveis antes do awk começar a digitalizar um ficheiro de texto. Por exemplo, pode definir os separadores de campos de entrada e saída dentro do seu script awk definindo-os numa declaração BEGIN. Este exemplo adapta o script simples do artigo anterior para um ficheiro com campos delimitados por vírgulas em vez de espaço em branco:

END comando

O comando END, tal como BEGIN, permite-lhe executar acções em awk depois de completar a sua digitalização através do ficheiro de texto que está a processar. Se quiser imprimir resultados acumulados de algum valor em todos os registos, só pode fazê-lo depois de todos os registos terem sido digitalizados e processados.

Os comandos BEGIN e END funcionam apenas uma vez cada um. Todas as regras entre eles correm zero ou mais vezes em cada registo. Por outras palavras, a maior parte do seu script awk é um loop que é executado em cada nova linha do ficheiro de texto que está a processar, com excepção das regras BEGIN e END, que correm antes e depois do loop.

Aqui está um exemplo que não seria possível sem o comando END. Este script aceita valores da saída do comando df Unix e incrementa duas variáveis personalizadas (usadas e disponíveis) com cada novo registo.

$1 != "tempfs" {
used += $3;
available += $4;
}
END {
printf "%d GiB used\n%d GiB available\n", used/2^20, available/2^20;
}

Guardar o script como total.awk e experimentá-lo:

df -l | awk -f total.awk

As variáveis usadas e disponíveis actuam como variáveis em muitas outras linguagens de programação. Cria-as arbitrariamente e sem declarar o seu tipo, e adiciona-lhes valores à sua vontade. No final do loop, o script adiciona os registos nas respectivas colunas e imprime os totais.

Math

Como provavelmente se pode ver por todos os operadores lógicos e cálculos casuais até agora, awk faz as contas de forma bastante natural. Isto torna-a, sem dúvida, uma calculadora muito útil para o seu terminal. Em vez de lutar para se lembrar da sintaxe bastante invulgar de bc, pode simplesmente usar awk juntamente com a sua função especial BEGIN para evitar a exigência de um argumento de ficheiro:

$ awk 'BEGIN { print 2*21 }'
42
$ awk 'BEGIN {print 8*log(4) }'
11.0904

Admittedly, isso ainda é muita digitação para matemática simples (e não tão simples), mas não seria preciso muito esforço para escrever um frontend, que é um exercício para você explorar.

Este artigo é adaptado de um episódio da Rádio Pública Hacker, um podcast de tecnologia comunitária.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *