Percursos
/
AWK
AWK
/
Programa
/
Fundamentos
Fu

Fundamentos em AWK

1 exercício

Sobre Fundamentos

Vamos referir-nos à linguagem como AWK e ao executável que interpreta programas AWK como awk ou gawk.

Padrões e ações

Um programa AWK é composto por pares padrão-ação

pattern1 { action1 }
pattern2 { action2 }
...

Um padrão pode ser uma expressão regular para comparar com a entrada. Também pode ser qualquer expressão que resulte num valor verdadeiro/falso.

Uma ação é um ou mais comandos AWK. As chavetas que a envolvem são obrigatórias.

Se o resultado do padrão for verdadeiro, a ação correspondente é avaliada.

Registos e campos

O AWK analisa a entrada como uma série de registos. Cada registo é dividido em zero ou mais campos.

O comportamento predefinido é:

  • dividir a entrada em registos usando a nova linha como «separador de registos», de modo que cada linha é um registo.
  • dividir o registo em campos usando espaços em branco como «separador de campos», de modo que cada palavra é um campo.

Padrões e ações, continuação

O padrão pode ser omitido, e nesse caso a ação é avaliada para cada registo de entrada.

A ação pode ser omitida, e nesse caso a ação predefinida é imprimir o registo atual.

Padrões especiais

Existem dois padrões especiais que são usados com frequência.

  • BEGIN avalia a ação associada antes de ser consumida qualquer entrada.
  • END avalia a ação associada depois de toda a entrada ser consumida.

Variáveis de campo

Referes-te aos campos como $1, $2, $3, etc.

O registo atual é $0.

Caution

Para ser explícito, estes não são, em sentido estrito, «variáveis». O $ pode ser considerado um operador que obtém o valor do número de campo indicado. Vamos aprofundar isto em conceitos posteriores.

Eis algumas outras variáveis incorporadas usadas com frequência.

Variáveis incorporadas que controlam a análise da entrada

  • RS é o separador de registos da entrada. Como já foi referido, o seu valor predefinido é a nova linha.
  • FS é o separador de campos da entrada.

Estas variáveis são frequentemente definidas no bloco de ação BEGIN.

Variáveis incorporadas que transmitem informação

Estas variáveis são definidas automaticamente pelo AWK durante a execução do programa.

  • NF guarda o número de campos do registo atual.
    • Para obteres o valor do último campo, usa $NF.
  • NR guarda o número do registo atual.
    • Quando estão a ser processados vários ficheiros de entrada, NR contém o número total de registos processados até ao momento.
  • FNR guarda o número do registo atual do ficheiro de entrada atual.
    • Para ilustrar a diferença entre NR e FNR, eis um idioma AWK comum.
      NR == FNR {action}
      
      Isto significa «se o número de registo acumulado for igual ao número de registo do ficheiro atual». Isto só pode ser verdadeiro para registos do primeiro ficheiro de entrada.

Veracidade

O AWK usa o mesmo conceito de veracidade que o C:

  • O número 0 é falso.
  • Qualquer outro número é verdadeiro.

Como o AWK é uma linguagem de processamento de texto, os valores de verdade estendem-se às strings.

  • Uma string vazia "" é falsa.
  • Qualquer string não vazia é verdadeira.
Note

O AWK usa o mesmo conceito de veracidade que o C

O AWK surgiu nos Bell Labs na década de 1970, no mesmo ambiente onde o C foi inventado. O C teve uma grande influência na sintaxe do AWK.

Caution

Uma particularidade a que deves estar atento

  • O número 0 é falso.
  • A string não vazia "0" é verdadeira!

Vamos aprofundar os tipos de dados do AWK em conceitos posteriores.

Comentários

Os comentários começam com o caráter # e prolongam-se até ao fim da linha.

Como fornecer entrada ao awk

O awk pode ler a entrada a partir de ficheiros ou da entrada padrão. Qualquer uma destas técnicas funciona.

awk '/regex/ {print $1}' file1 file2 ...

awk '/regex/ {print $1}' < file

some_command_here | awk '/regex/ {print $1}'

Exemplos

Em sistemas do tipo Unix, /etc/passwd contém informação sobre os utilizadores. Cada utilizador é descrito numa linha separada, com os campos separados por dois pontos.

Para listar os nomes de utilizador:

awk '
    BEGIN { FS = ":" }
    { print $1 }
' /etc/passwd

Repara que a ação {print $1} não tem padrão, pelo que é executada para cada registo.

Se quisermos limitar a saída apenas aos utilizadores que usam o bash como shell de início de sessão, podemos fazer:

awk '
    BEGIN { FS = ":" }
    $7 == "/bin/bash" { print $1 }
' /etc/passwd

Mais alguns exemplos

Eis alguns programas awk que produzem os mesmos resultados que outros comandos Unix comuns.

  • Mostrar o conteúdo de um ficheiro

    cat file.txt
    
    awk '1' file.txt
    
  • Procurar padrões num ficheiro

    grep 'foo.*bar' file.txt
    
    awk '/foo.*bar/' file.txt
    
  • Mostrar apenas algumas linhas no início de um ficheiro

    head -n 20 file.txt
    
    awk '
        1
        NR == 20 {exit}
    ' file.txt
    
  • Substituir texto num ficheiro

    sed 's/foo/bar/' file.txt
    
    awk '{sub(/foo/, "bar")};1' file.txt
    # or more readably
    awk '
        {
            sub(/foo/, "bar")
            print
        }
    ' file.txt
    
Editar via GitHub A ligação abre numa nova janela ou separador

Aprende Fundamentos