Ch1

Table of Contents

1 Getting Started

Suponha que tenhamos um arquivo que contenha o nome, o salário por hora e quantas horas foram trabalhadas chamado "emp.data":

Beth 4.00 0

Dan 3.75 0

Kathy 4.00 10

Mark 5.00 20

Mary 5.50 22

Susie 4.25 18

Agora, queremos imprimir o nome e quando deve ser pago a cada empregado que trabalhou:

$3 > 0 { print $1, $2 * $3}

Pode-se fazer direto da linha de comando com: $ gawk '$3 > 0 { print $1, $2 * $3 }' emp.data

Ambos imprimem: Kathy 40

Mark 100

Mary 121

Susie 76.5

O programa é muito simples, é um "pattern-action statement": o padrão $3 > 0 é satisfeito por todas as linhas cuja terceira coluna é maior que 0 e, então, é executado o bloco entre {}.

1.1 A estrutura de um programa awk

Nesse capítulo, os programas são todos da forma: pattern { action }

pattern { action }

pattern { action }

Toda linha de input é testada para todos os padrões.

Tanto o padrão como a ação podem ser omitidos (claramente não ao mesmo tempo). Se um padrão não possui ação, todas as linhas (ou o outro divisor) que satisfazem o padrão serão impressas. Por exemplo, no arquivo emp.data, o programa '$3 == 0' imprime as linhas da Beth e do Dan. Um ação sem padrão é executada para todas as linhas.

2 Output Simples

Existem dois tipos de dados em awk: números e strings.

O awk lê o input uma linha por vez e a quebra em campos, que são, por default, uma sequência de caracteres que não contém whitespace.

O primeiro campo é denotado por $1, o segundo por $2 e assim por diante. A linha inteira é denotada por $0.

2.1 NF

A variável NF armazena o número de campos na linha atual. Logo, o programa

{ print NF, $1, $NF }

imprime o número de campos, o primeiro e o último campo de cada linha.

2.2 NR

Outra variável built-in é NR, que armazena o número de linhas lidas até o momento. O programa a seguir imprime cada linha com seu número na frente:

{ print NR, $0 }

No caso do arquivo emp.data, a saída é 1 Beth 4.00 0 2 Dan 3.75 0 3 Kathy 4.00 10 4 Mark 5.00 20 5 Mary 5.50 22 6 Susie 4.25 18

3 Output com frescuras

Pode-se usar printf.

O livro diz que para se ordenar a saída é para usar um pipe com sort. Eu diria que é justo.

4 Seleção

4.1 Regex

São indicadas por "/ /". O padrão Susie imprime as linhas que contém Susie.

4.2 Operadores lógicos

Os mesmos operadores lógicos de C podem ser usados nos padrões.

4.3 BEGIN e END

O padrão BEGIN é executado antes da leitura da primeira linha e o padrão END ao fim da leitura.

Por exemplo, o programa

BEGIN { print "NAME     RATE    HOURS"; print "" }
      {print}

Imprime um cabeçalho.

5 Computing com awk

5.1 Contando

O programa a seguir usa a variável emp para contar os empregados que trabalharam mais de 15hs:

$3 > 15 { emp = emp + 1 }
END     { print emp, "employees worked more than 15 hours"}

5.2 Texto

As variáveis de awk podem armazenar strings ou números:

$2 > maxrate { maxrate = $2; maxemp = $1 }
END { print "highest hourly rate:", maxrate, "for", maxemp }

5.3 Concatenação de Strings

Strings são concatenadas simplesmente escrevendo-as uma do lado da outra.

{ names = names $1 " " }
END     { print names }

5.4 Funções built-in

As matemáticas padrão e algumas para texto. Uma útil é "length" que é o número de caracteres numa string.

6 Fluxo

6.1 if - else, for, while

C-like.

7 Arrays

# reverse - output = input in reverse order by line

{ 
line[NR] = $0
} # armazena a linha

END
{ i = NR
     while (i > 0) {
          print line[i]
          i = i - 1
     }
}

8 One-liners

# Número de linhas
END { print NR }

# Imprime a décima linha
NR == 10

# Imprime o último campo de cada linha
{ print $NF }

# Imprime o último campo da última linha
{ campo = $NF }
END { print campo }

# Imprime toda linha com mais de quatro campos
NF > 4

# Imprime toda linha cujo último campo é maior que 4
$NF > 4

# Imprime o número total de campos na entrada
{ nf = nf + NF }
END { print nf }

# Imprime quantas linhas tem "palavra"
/palavra/ { nlines = nlines + 1}
END { print nlines }

# Imprime o maior primeiro campo e a linha que o contém
$1 > max { max = $1; maxline = $0 }
END {print max, maxline }

# Imprime toda linha com pelo menos um campo
NF > 0

# Imprime toda linha com mais de 80 caracteres
length($0) > 80

# Imprime o número de campos da linha seguido da linha
{ print NF, $0 }

# Imprime os dois primeiros campos, o segundo antes do primeiro
{ print $2, $1 }

# Troca os dois primeiros campos e imprime a linha
{ temp = $1; $1 = $2; $2 = temp; print }

# Imprime toda linha com o primeiro campo substituído pelo número da linha
{ $1 = NR; print }

# Imprime toda linha sem o segundo campo
{ $2 = ""; print }

# Imprime os campos em ordem reversa
{ for (i = NF; i > 0; i = i - 1) printf("%s ", $i)
     printf("\n")
}

# Imprime a soma dos campos
{ sum = 0
  for (i = 1; i <= NF; i = i + 1) sum = sum + i
  print sum
}

# Soma todas os campos de todas as linhas
{ for (i = 1; i <= NF; i = i + 1) sum = sum + $i }
END { print sum }

# Imprime toda linha substituindo seus campos pelo seu valor absoluto
{ for (i = 1; i <= NF; i = i + 1) if ($i < 0) $i = -$i
  print
}