Básico

Básico

Exercício de aprendizagem

Introdução

Fundamentos

Vamos chamar à linguagem AWK e ao executável que interpreta programas AWK 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 que é comparada com a entrada. Também pode ser qualquer expressão que resulte num valor verdadeiro ou 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 é executada.

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 mudança de linha como "separador de registos", pelo que cada linha é um registo.
  • dividir o registo em campos usando espaços em branco como "separador de campos", pelo que cada palavra é um campo.

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

O padrão pode ser omitido, e nesse caso a ação é executada 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 executa a ação associada antes de qualquer entrada ser lida.
  • END executa a ação associada depois de toda a entrada ser lida.

Variáveis de campos

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

O registo atual é $0.

Aqui estão 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 foi referido, o seu valor predefinido é a mudança de 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 obter o valor do último campo, usa $NF.
  • NR guarda o número do registo atual.
    • Quando são 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, aqui está uma construção típica de AWK.
      NR == FNR {action}
      
      Isto significa "se o número acumulado de registos for igual ao número de registos do ficheiro atual." Isto só pode ser verdadeiro para registos do primeiro ficheiro de entrada.

Valores verdadeiros e falsos

O AWK usa o mesmo conceito de valores verdadeiros e falsos 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.

Comentários

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

Exemplos

Nos sistemas do tipo Unix, o ficheiro /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, por isso é 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

Instruções

Era uma vez uma cidade movimentada chamada Cyberspace. Cyberspace era uma metrópole digital, com milhões de habitantes a iniciar e a terminar sessão todos os dias. Para acompanhar todos estes utilizadores, Cyberspace tinha um ficheiro especial chamado /etc/passwd.

O ficheiro /etc/passwd era como uma lista telefónica da cidade. Nele estava listado cada utilizador que tinha uma conta no sistema, juntamente com algumas informações importantes sobre cada utilizador:

n campo
1 nome de utilizador
2 palavra-passe ("x" indica que a palavra-passe real está guardada noutro sítio, por segurança)
3 UID, um identificador numérico único de utilizador
4 GID, um identificador numérico único de grupo (normalmente igual ao UID)
5 informações do utilizador (normalmente o nome completo do utilizador, mas pode incluir outras informações)
6 diretório pessoal
7 shell de login

Os campos são separados por um caráter de dois pontos. Esta é uma entrada típica:

glennj:x:1010:1010:Glenn Jackman:/home/glennj:/usr/local/bin/fish

O ficheiro era gerido por uma equipa de administradores de sistemas, responsáveis por criar novas contas, atualizar contas existentes e remover contas antigas. Os administradores de sistemas eram os guardiões do Cyberspace, garantindo que apenas utilizadores autorizados conseguiam aceder ao sistema.

Um dia, foi contratado um novo administrador de sistemas chamado Alex para se juntar à equipa. O Alex ficou contente por assumir o cargo e depressa aprendeu os meandros do ficheiro /etc/passwd. Aprendeu a adicionar novos utilizadores ao sistema, a atualizar informações de utilizadores e a remover utilizadores antigos.

Enquanto trabalhava no ficheiro /etc/passwd, o Alex reparou em algo estranho. Alguns utilizadores tinham diretórios pessoais estranhos ou invulgares. Alguns utilizadores tinham o diretório pessoal definido como /dev/null, enquanto outros tinham o diretório pessoal definido como caminhos estranhos que não existiam.

O Alex percebeu que estes utilizadores não eram pessoas reais, mas sim contas falsas criadas por hackers. Os hackers tinham encontrado uma forma de explorar uma vulnerabilidade no sistema e tinham criado estas contas falsas para obter acesso ao Cyberspace.

O Alex sabia que era preciso agir. Usou o awk para analisar o ficheiro /etc/passwd e escreveu um script para identificar todas as contas falsas. Depois trabalhou com o resto da equipa para remover estas contas e corrigir a vulnerabilidade que tinha permitido aos hackers criá-las.

Graças ao uso que o Alex fez do awk, a equipa conseguiu identificar e remover as contas falsas e tornar o Cyberspace um lugar mais seguro para todos. Os administradores de sistemas continuaram a gerir o ficheiro /etc/passwd, mantendo-o atualizado e seguro e garantindo que apenas utilizadores autorizados conseguiam aceder ao sistema.

Agora é a tua vez de seres um administrador de sistemas como o Alex.

Note

Aqui está mais alguma sintaxe de AWK de que vais precisar para resolver este exercício.

  • Os operadores Boolean são semelhantes aos de outras linguagens:

    operação exemplo
    E expr1 && expr2
    OU expr1 || expr2
    NÃO ! expr
  • Chamar uma função tem uma sintaxe familiar:

    function greet(name) {
        print "Hello", name
    }
    BEGIN {
        greet("Mary")   # prints "Hello Mary"
    }
    

1. Lista os nomes de utilizador

Escreve um programa awk que imprima o primeiro campo separado por dois pontos em cada linha do ficheiro passwd.

2. Imprime os números de linha

Escreve um comando awk que imprima o número de linha de cada registo do ficheiro de entrada. Imprime apenas o número de linha, e mais nenhuma informação.

3. Imprime os registos com diretórios pessoais inválidos.

No Cyberspace, um diretório pessoal "válido" começa por /home ou /root. Imprime os registos do ficheiro de entrada com diretórios pessoais inválidos.

4. Imprime os utilizadores válidos que usam o bash

Imprime os registos em que o diretório pessoal é válido e o shell de login é o bash.


Fonte

Conversa com o ChatGPT
Editar via GitHub A ligação abre numa nova janela ou separador
AWK Exercism

Estás pronto para começar Básico?

Inscreve-te no Exercism para aprenderes e dominares AWK com 3 conceitos92 exercícios, e mentoria humana real, tudo grátis.