Introdução
Os utilitários do Linux frequentemente seguem a filosofia de design do Unix. Incentiva-se que as ferramentas sejam pequenas, usem arquivos de texto simples para entrada e saída, e operem de forma modular. Devido a essa herança, temos uma ótima funcionalidade de processamento de texto com ferramentas como sed e awk
.
awk
é tanto uma linguagem de programação quanto um processador de texto que você pode usar para manipular dados de texto de maneiras muito úteis. Neste guia, você explorará como usar a ferramenta de linha de comando awk
e como usá-la para processar texto.
Sintaxe Básica
O comando awk
está incluído por padrão em todos os sistemas Linux modernos, então você não precisa instalá-lo para começar a usá-lo.
awk
é mais útil ao lidar com arquivos de texto formatados de maneira previsível. Por exemplo, é excelente para analisar e manipular dados tabulares. Ele opera em uma base de linha por linha e itera por todo o arquivo.
Por padrão, ele usa espaços em branco (espaços, tabulações, etc.) para separar campos. Felizmente, muitos arquivos de configuração no seu sistema Linux usam esse formato.
O formato básico de um comando awk
é:
Você pode omitir a parte de busca ou a parte de ação de qualquer comando awk
. Por padrão, a ação realizada se a parte “ação” não for fornecida é “print”. Isso simplesmente imprime todas as linhas que correspondem.
Se a parte de busca não for fornecida, o awk
realiza a ação listada em cada linha.
Se ambos forem fornecidos, o awk
usa a parte de busca para decidir se a linha atual reflete o padrão e, em seguida, executa as ações nas correspondências.
Em sua forma mais simples, você pode usar o awk
como cat
para imprimir todas as linhas de um arquivo de texto na tela.
Crie um arquivo favorite_food.txt
que lista as comidas favoritas de um grupo de amigos:
Agora use o comando awk
para imprimir o arquivo na tela:
Você verá o arquivo impresso na tela:
Outputcarrot sandy
wasabi luke
sandwich brian
salad ryan
spaghetti jessica
Isso não é muito útil. Vamos experimentar as capacidades de filtragem de pesquisa do awk
pesquisando o arquivo pelo texto “sand”:
Outputcarrot sandy
sandwich brian
Como você pode ver, o awk
agora imprime apenas as linhas que contêm os caracteres “sand”.
Usando expressões regulares, você pode segmentar partes específicas do texto. Para exibir apenas a linha que começa com as letras “sand”, use a expressão regular ^sand
:
Desta vez, apenas uma linha é exibida:
Outputsandwich brian
Da mesma forma, você pode usar a seção de ação para especificar quais informações deseja imprimir. Por exemplo, para imprimir apenas a primeira coluna, use o seguinte comando:
Outputsandwich
Você pode fazer referência a cada coluna (delimitada por espaços em branco) por meio de variáveis associadas ao número da coluna. Por exemplo, a primeira coluna é $1
, a segunda é $2
, e você pode referenciar a linha inteira com $0
.
Variáveis Internas e Formato Expandido
O comando awk
usa algumas variáveis internas para atribuir certas informações enquanto processa um arquivo.
As variáveis internas que o awk
utiliza são:
- FILENAME: Referencia o arquivo de entrada atual.
- FNR: Referencia o número do registro atual em relação ao arquivo de entrada atual. Por exemplo, se você tiver dois arquivos de entrada, isso informaria o número do registro de cada arquivo, em vez do total.
- FS: O separador de campo atual usado para denotar cada campo em um registro. Por padrão, isso é definido como espaço em branco.
- NF: O número de campos no registro atual.
- NR: O número do registro atual.
- OFS: O separador de campo para os dados de saída. Por padrão, isso é definido como espaço em branco.
- ORS: O separador de registro para os dados de saída. Por padrão, isso é um caractere de nova linha.
- RS: O separador de registros usado para distinguir registros separados no arquivo de entrada. Por padrão, isso é um caractere de nova linha.
Você pode alterar os valores dessas variáveis conforme necessário para corresponder às necessidades de seus arquivos. Geralmente, você faz isso durante a fase de inicialização do seu processamento.
Isso nos leva a outro conceito importante. A sintaxe do awk
é um pouco mais complexa do que a que você usou até agora. Existem também blocos opcionais BEGIN
e END
que podem conter comandos para executar antes e depois do processamento do arquivo, respectivamente.
Isso faz com que nossa sintaxe expandida se pareça com isso:
As palavras-chave BEGIN
e END
são conjuntos específicos de condições, assim como os parâmetros de pesquisa. Elas correspondem antes e depois do documento ter sido processado.
Isso significa que você pode alterar algumas das variáveis internas na seção BEGIN
. Por exemplo, o arquivo /etc/passwd
é delimitado por dois pontos (:
) em vez de espaços em branco.
Para imprimir a primeira coluna deste arquivo, execute o seguinte comando:
Outputroot
daemon
bin
sys
sync
games
man
. . .
Você pode usar os blocos BEGIN
e END
para imprimir informações sobre os campos que está imprimindo. Use o seguinte comando para transformar os dados do arquivo em uma tabela, bem espaçada com tabulações usando \t
:
Você verá esta saída:
OutputUser UID GID Home Shell
--------------
root 0 0 /root /bin/bash
daemon 1 1 /usr/sbin /bin/sh
bin 2 2 /bin /bin/sh
sys 3 3 /dev /bin/sh
sync 4 65534 /bin /bin/sync
. . .
---------
File Complete
Como você pode ver, é possível formatar as coisas bastante bem aproveitando algumas das características do awk
.
Cada uma das seções expandidas é opcional. Na verdade, a seção de ação principal em si também é opcional se outra seção for definida. Por exemplo, você pode fazer coisas como esta:
E você verá esta saída:
OutputWe can use awk like the echo command
Agora vamos ver como procurar texto dentro dos campos da saída.
Pesquisa de Campo e Expressões Compostas
Em um dos exemplos anteriores, você imprimiu a linha no arquivo favorite_food.txt
que começava com “sand”. Isso foi fácil porque você estava procurando pelo início da linha inteira.
E se você quisesse descobrir se um padrão de pesquisa corresponde ao início de um campo em vez disso?
Crie uma nova versão do arquivo favorite_food.txt
que adiciona um número de item na frente da comida de cada pessoa:
Se você quiser encontrar todos os alimentos deste arquivo que começam com “sa”, você pode começar tentando algo assim:
Isso mostra todas as linhas que contêm “sa”:
Output1 carrot sandy
2 wasabi luke
3 sandwich brian
4 salad ryan
Aqui, você está correspondendo a qualquer instância de “sa” na palavra. Isso acaba incluindo coisas como “wasabi”, que têm o padrão no meio, ou “sandy”, que não está na coluna que você deseja. Neste caso, você está interessado apenas em palavras que começam com “sa” na segunda coluna.
Você pode dizer ao awk
para apenas fazer correspondência no início da segunda coluna usando este comando:
Como você pode ver, isso nos permite procurar apenas no início da segunda coluna por uma correspondência.
A parte field_num ~
especifica que o awk
deve prestar atenção apenas na segunda coluna.
Output3 sandwich brian
4 salad ryan
Você também pode procurar facilmente por coisas que não correspondam incluindo o caractere “!” antes do til (~). Este comando retornará todas as linhas que não têm um alimento que comece com “sa”:
Output1 carrot sandy
2 wasabi luke
5 spaghetti jessica
Se você decidir mais tarde que está interessado apenas em linhas que não começam com “sa” e o número do item é menor que 5, você pode usar uma expressão composta como esta:
Isso introduz alguns novos conceitos. O primeiro é a capacidade de adicionar requisitos adicionais para a linha corresponder usando o operador &&
. Usando isso, você pode combinar um número arbitrário de condições para a linha corresponder. Neste caso, você está usando esse operador para adicionar uma verificação de que o valor da primeira coluna é menor que 5.
Você verá esta saída:
Output1 carrot sandy
2 wasabi luke
Você pode usar o awk
para processar arquivos, mas também pode trabalhar com a saída de outros programas.
Processando Saída de Outros Programas
Você pode usar o comando awk
para analisar a saída de outros programas em vez de especificar um nome de arquivo. Por exemplo, você pode usar o awk
para extrair o endereço IPv4 do comando ip
.
O comando ip a
exibe o endereço IP, endereço de broadcast e outras informações sobre todas as interfaces de rede em sua máquina. Para exibir as informações para a interface chamada eth0
, use este comando:
Você verá os seguintes resultados:
Output2571: eth0@if2572: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:0b brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.11/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
Você pode usar o awk
para direcionar a linha inet
e então imprimir apenas o endereço IP:
A bandeira -F
informa ao awk
para delimitar por barras diagonais ou espaços usando a expressão regular [\/ ]+
. Isso divide a linha inet 172.17.0.11/16
em campos separados. O endereço IP está no terceiro campo porque os espaços no início da linha também contam como um campo, já que você delimitou por espaços e barras. Observe que o awk
tratou espaços consecutivos como um único espaço neste caso.
A saída mostra o endereço IP:
Output172.17.0.11
Você encontrará muitos lugares onde pode usar o awk
para pesquisar ou analisar a saída de outros comandos.
Conclusão
Até agora, você deve ter uma compreensão básica de como pode usar o comando awk
para manipular, formatar e imprimir seletivamente arquivos de texto e fluxos de texto. Awk é um tópico muito mais amplo, porém, e na verdade é uma linguagem de programação completa com atribuição de variáveis, estruturas de controle, funções integradas e muito mais. Você pode usá-lo dentro de seus próprios scripts para formatar texto de maneira confiável.
Para saber mais sobre awk
, você pode ler o livro de domínio público gratuito de seus criadores que entra em muito mais detalhes.