Vamos chamar à linguagem AWK e ao executável que interpreta programas AWK awk ou gawk.
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.
O AWK analisa a entrada como uma série de registos. Cada registo é dividido em zero ou mais campos.
O comportamento predefinido é:
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.
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.Referes-te aos campos como $1, $2, $3, etc.
O registo atual é $0.
Aqui estão outras variáveis incorporadas usadas com frequência.
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.
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.
$NF.NR guarda o número do registo atual.
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.
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.O AWK usa o mesmo conceito de valores verdadeiros e falsos que o C.
0 é falso.Como o AWK é uma linguagem de processamento de texto, os valores de verdade estendem-se às strings.
"" é falsa.Os comentários começam com o caráter # e vão até ao fim da linha.
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
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.
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"
}
Escreve um programa awk que imprima o primeiro campo separado por dois pontos em cada linha do ficheiro passwd.
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.
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.
Imprime os registos em que o diretório pessoal é válido e o shell de login é o bash.
Inscreve-te no Exercism para aprenderes e dominares AWK com 3 conceitos92 exercícios, e mentoria humana real, tudo grátis.