Primeiros passos com o comando Awk
Awk é uma poderosa linguagem de programação de processamento de dados integrada em quase todos os sistemas *nix. Aparentemente, parece uma linguagem de programação de uso geral, mas foi construída para receber entradas e executar ações com base nessas entradas. Se você precisar processar texto com base em certas condições, o awk quase sempre fará o trabalho mais rapidamente do que uma linguagem de uso geral como C. Ele também é interpretado, evitando o prolixo processo de compilação e depuração de linguagens compiladas.
Curiosidade extra: o nome estranho do programa é uma inicial dos nomes de seus programadores: Alfred Aho, Peter Weinberger e Brian >Kernighan
Sintaxe básica do Awk
Quando invocado na linha de comando, o awk segue o padrão básico abaixo:
pattern { action } file pattern { action } file ...
O Awk executará a ação sempre que o padrão corresponder ao arquivo especificado. Se você não especificar um arquivo, o awk será executado na saída padrão. Ao combinar padrões, o awk pode receber expressões regulares e também entradas programáticas. Vamos considerar este exemplo básico abaixo:
awk '/com/ { print $0 }' emails
Este programa de uma linha imprimirá cada linha do arquivo "emails" que contém os caracteres com
. Em awk $0
refere-se à linha atual, que também é o comportamento padrão. A linha poderia ter sido escrita sem $0,
e teria funcionado de forma idêntica.
Imprimindo campos
Como o awk pode identificar e analisar separadores de campos, ele é útil para imprimir colunas ou linhas específicas de dados. Usaremos o arquivo "/etc/passwd" para este exemplo.
awk -F":" '{ print $1 }' /etc/passwd
Este programa de uma linha faz algumas coisas. A flag -F
indica que o próximo caractere (:
neste exemplo) deve ser interpretado como o separador de campos. Awk eles imprime o primeiro campo, especificado por $1
.
Também podemos imprimir mais de um campo por vez, especificando os campos sequencialmente:
awk -F":" '{ print $4 " " $5}' /etc/passw
Ele produzirá uma saída semelhante à seguinte.
Isso imprime o quarto e quinto campos do arquivo passwd
com um espaço entre eles. Observe que o espaço está entre aspas duplas. Isso o especifica como um caractere literal no comando de impressão, portanto, é impresso como está escrito. Também podemos adicionar literais mais complicados para limpar nossa saída:
awk -F":" '{ print "process: " $5 "\t\t " "directory: "$6}' /etc/passwd
Isso imprimirá a saída com etiquetas para identificação. E podemos enviar tudo isso para um novo arquivo usando um sinal de intercalação (>).
awk -F":" '{ print "process: " $5 "\t\t " "directory: "$6}' /etc/passwd > processes.txt
Podemos combinar o que sabemos até agora para processar dados extensivamente. Por exemplo, podemos usar expressões regulares para imprimir todas as linhas de um documento que contém um número de telefone válido nos EUA.
awk '/^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$/ { print }' contacts
Expandindo o poder de correspondência do comando Awk
O Awk também pode processar informações usando uma variedade de operandos. Isso inclui operandos padrão como ==
, <
, >
, <=
, >=
e !=
, bem como operandos específicos do awk ~
e !~,
que significam "corresponde" e "não corresponde "respectivamente. Esses operandos são usados ao comparar expressões regulares com lógica booleana, bem como frases programáticas mais padrão.
Exemplos de comandos Awk
awk 'length($0) > 80' data
Imprime todas as linhas com mais de oitenta caracteres no arquivo “data”. Observe a falta de uma instrução print: na ausência de uma ação especificada, o awk imprimirá a linha completa sempre que um padrão corresponder.
$1 == "user" { print }
Imprime todas as linhas onde o primeiro campo é igual à string “usuário”. Sem um sinalizador -F
, o awk usará espaço em branco como separador de campo padrão. Além disso, observe que awk e o arquivo não são especificados. Isso é para uso em scripts em arquivos separados, conforme abordado abaixo.
$5 ~ /root/ { print $3 }
Imprime o terceiro campo sempre que o quinto campo corresponder à expressão regular /root/
.
{ if ( $5 !~ /root/ ) { print $3 } }
Quando o campo 5 não corresponder a /root/
, imprima o campo três. Isso usa a instrução if
do tipo C, que também é compatível com o awk. Este formato permite mais flexibilidade para programadores familiarizados com linguagens de uso geral.
Salvando scripts em arquivos
Os scripts Awk também podem ser salvos em arquivos que permitem salvar programas mais complexos:
awk -f ~/scripts/program.awk data
Ao usar o sinalizador -f
, o awk executa o script no caminho de arquivo especificado, ou seja, program.awk
. Os comandos desse programa processarão o arquivo “dados”.
As ações também podem ser executadas antes e depois do programa, usando BEGIN
e END
:
BEGIN { FS=":" } # indicates that : is the field separator for the program. #operations END { print "You're done" } # prints a joyful message for the user
Como você pode ver acima, o símbolo #
inicia um comentário, que dura até o final da linha.
Conclusão
Este guia aborda apenas os elementos mais básicos do awk. Há muito mais para construir e explorar além disso. Examine a documentação GNU para awk ou The Awk Programming Language, e o livro awk escrito pelos desenvolvedores do programa.