Comando awk: imprimir campos, delimitador -F e padrões condicionais

Ambiente de testeFamília RHELAlmaLinux 9.8conta rootVerificado em 2026-10-29

O comando awk é uma ferramenta do Linux que lê um arquivo de texto linha por linha, divide cada linha em campos pelos espaços ou pelo delimitador que você indicar e seleciona só os campos das linhas que atendem a uma condição para mostrá-los ou fazer cálculos. Em um servidor AlmaLinux 9, contamos as requisições por IP e a quantidade por código de status de um arquivo de exemplo com o log de acesso de um servidor web com uma única linha ligada ao sort por pipe, e as três respostas 404 das doze linhas eram todas requisições a wp-login.php e .env vindas de um mesmo IP.

A saída abaixo foi obtida com a conta root dentro de uma pasta de trabalho em um servidor AlmaLinux 9.8. O log de acesso, a lista de contas, os registros de vendas e o arquivo de pontuações são arquivos de exemplo criados para o teste, e os endereços IP e nomes de conta neles também são valores de exemplo.

1️⃣ Uso básico do comando awk

  • ↪️ Números de campo e print

O awk divide cada linha lida pelos espaços e numera os campos a partir do início como $1, $2, $3. Conferimos isso com scores.txt, em que nome, resultado e pontuação são separados por espaços.

cat scores.txt
alice   pass  82
bob     fail  47
carol   pass  91
dave    pass  68
erin    fail  55

As chaves dentro das aspas simples contêm a ação executada em cada linha, e se você listar números de campo depois de print, separados por vírgulas, só esses campos saem. Ao mostrar o primeiro e o terceiro campos, ficam só o nome e a pontuação.

awk '{print $1, $3}' scores.txt
alice 82
bob 47
carol 91
dave 68
erin 55

Se você tirar a vírgula entre os campos e escrever $1 $3, os dois valores saem colados, sem espaço. A vírgula de print insere o separador de saída (um espaço por padrão), e valores escritos lado a lado sem vírgula viram uma única string.

awk '{print $1 $3}' scores.txt
alice82
bob47
carol91
dave68
erin55

NR é o número da linha lida até o momento, e NF é a quantidade de campos dessa linha. $NF indica o último campo, então você pode escolher a última coluna mesmo que o número de campos mude de linha para linha.

awk '{print NR, NF, $NF}' scores.txt
1 3 82
2 3 47
3 3 91
4 3 68
5 3 55

O log de acesso de um servidor web também é separado por espaços, então os campos são escolhidos do mesmo jeito. Os números de campo da primeira linha do log de teste são os seguintes.

CampoValor na primeira linhaSignificado
$1192.0.2.10IP do cliente
$4[29/Oct/2026:00:01:12Data e hora da requisição
$6"GETMétodo da requisição (com aspas duplas na frente)
$7/index.htmlURL da requisição
$9200Código de status
$105120Bytes enviados
$11"-"Página anterior (Referer)
$12~$15"Mozilla/5.0 (X11; Linux x86_64)"User agent (dividido a cada espaço)

Mostramos $1, $7 e $9, que correspondem ao IP do cliente, à URL da requisição e ao código de status.

awk '{print $1, $7, $9}' access.log
192.0.2.10 /index.html 200
198.51.100.7 /about.html 200
192.0.2.10 /images/logo.png 200
203.0.113.25 /wp-login.php 404
203.0.113.25 /wp-login.php 404
192.0.2.10 /contact.html 200
198.51.100.7 /old-page.html 301
203.0.113.25 /.env 404
192.0.2.44 /index.html 200
198.51.100.7 /api/search?q=awk 500
192.0.2.44 /images/logo.png 304
192.0.2.10 /index.html 200

Uma coluna com espaços no valor, como o user agent, é dividida em vários campos. NF foi 15 nas três primeiras linhas, e $NF é o último pedaço do user agent.

awk '{print NF, $NF}' access.log | head -3
15 x86_64)"
15 x86_64)"
15 x86_64)"

2️⃣ Definir o delimitador com awk -F

  • ↪️ Delimitadores de dois-pontos, vírgula e expressão regular

Em um arquivo cujas colunas são separadas por um símbolo que não seja espaço, escreva esse símbolo depois de -F. Ao mostrar $1 sem -F na lista de contas users.txt, criada no mesmo formato de /etc/passwd, a maioria das linhas saiu inteira.

awk '{print $1}' users.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
nobody:x:65534:65534:Kernel
user:x:1000:1000:Example
deploy:x:1001:1001:Deploy
backup:x:1002:1002::/home/backup:/sbin/nologin

O delimitador padrão é o espaço, então uma linha ligada só por dois-pontos tem um único campo. Só as linhas nobody, user e deploy, que têm um espaço na coluna de descrição, são cortadas nesse espaço.

Com -F:, os dois-pontos viram delimitador, e o nome da conta ($1) e o shell de login ($7) ficam separados.

awk -F: '{print $1, $7}' users.txt
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
nobody /sbin/nologin
user /bin/bash
deploy /bin/bash
backup /sbin/nologin

Arquivos CSV separados por vírgula são divididos com -F,. Ao mostrar o item e a quantidade dos registros de vendas de sales.csv, o cabeçalho da primeira linha (item qty) é dividido do mesmo jeito e aparece junto.

awk -F, '{print $2, $3}' sales.csv
item qty
keyboard 2
mouse 5
monitor 1
keyboard 1
cable 10
mouse 2
monitor 2

-F, não serve para CSV com vírgulas dentro de colunas entre aspas duplas. Em quoted.csv, que tem vírgulas na coluna do item, os campos também são divididos nas vírgulas dentro das aspas, e no segundo campo fica só a parte inicial do nome do item.

awk -F, '{print $2}' quoted.csv
item
"cable
keyboard

Para esses arquivos, o manual oficial do GNU Awk apresenta a variável FPAT. Se você escrever a forma de um campo como expressão regular em vez de um delimitador, a coluna entre aspas sai como um único campo.

awk -v FPAT='([^,]*)|("[^"]*")' '{print $2}' quoted.csv
item
"cable, usb"
keyboard

Para usar vários delimitadores, escreva-os como expressão regular entre colchetes. Com os dois-pontos e a barra como delimitadores, $NF passa a ser o último nome do caminho do shell de login (bash, nologin).

awk -F'[:/]' '{print $1, $NF}' users.txt
root bash
bin nologin
daemon nologin
nobody nologin
user bash
deploy bash
backup nologin

3️⃣ Padrões condicionais do comando awk

  • ↪️ Expressões regulares, comparações e NR

Mesmo escolhendo campos, todas as linhas são mostradas. Para deixar só as linhas necessárias, coloque uma condição (padrão) antes das chaves. Uma string entre barras seleciona só as linhas que a contêm, e se você omitir a ação, a linha inteira é mostrada.

awk '/wp-login/' access.log
203.0.113.25 - - [29/Oct/2026:00:04:51 +0000] "POST /wp-login.php HTTP/1.1" 404 196 "-" "Mozilla/5.0 (X11; Linux x86_64)"
203.0.113.25 - - [29/Oct/2026:00:04:52 +0000] "POST /wp-login.php HTTP/1.1" 404 196 "-" "Mozilla/5.0 (X11; Linux x86_64)"

As linhas selecionadas são as mesmas do comando grep, e o awk pode escolher direto os campos dessas linhas e mostrá-los. Ao passar para o awk por pipe as mesmas duas linhas selecionadas com grep, ficam só o IP e o código de status.

grep wp-login access.log | awk '{print $1, $9}'
203.0.113.25 404
203.0.113.25 404

Os valores de campo são comparados com ==, !=, >, >=, <, <=. Selecionamos só as linhas com código de status ($9) 404 e mostramos o IP e a URL da requisição.

awk '$9 == 404 {print $1, $7}' access.log
203.0.113.25 /wp-login.php
203.0.113.25 /wp-login.php
203.0.113.25 /.env

Ao comparar com uma string, coloque o valor entre aspas duplas. Selecionamos só os nomes cujo segundo campo é pass.

awk '$2 == "pass" {print $1}' scores.txt
alice
carol
dave

A comparação numérica serve para selecionar por faixa, como com números de conta (UID). Ao selecionar contas com UID de 1000 ou mais, entra junto com as contas comuns também o nobody, cujo UID é 65534.

awk -F: '$3 >= 1000 {print $1, $3}' users.txt
nobody 65534
user 1000
deploy 1001
backup 1002

Duas condições são unidas com &&. Ao adicionar a condição de menos de 65534, o nobody sai e ficam só as três contas comuns e suas pastas pessoais.

awk -F: '$3 >= 1000 && $3 < 65534 {print $1, $6}' users.txt
user /home/user
deploy /home/deploy
backup /home/backup

[~] verifica se um campo corresponde a uma expressão regular, e [!~] se não corresponde. Ao selecionar as contas cujo shell de login ($7) termina em bash e as contas que não são nologin, saem as mesmas três contas.

awk -F: '$7 ~ /bash$/ {print $1}' users.txt
root
user
deploy
awk -F: '$7 !~ /nologin/ {print $1, $7}' users.txt
root /bin/bash
user /bin/bash
deploy /bin/bash

A condição NR seleciona por número de linha. Com NR > 1, a linha de cabeçalho do CSV sai e ficam só os registros de vendas.

awk -F, 'NR > 1 {print $2, $3}' sales.csv
keyboard 2
mouse 5
monitor 1
keyboard 1
cable 10
mouse 2
monitor 2

A saída de outros comandos também pode passar por pipe e ser dividida do mesmo jeito. Ao escolher o tamanho ($5) e o nome ($9) na saída de ls -l, a primeira linha saiu vazia, porque a primeira linha de ls -l, [total 24], não tem quinto nem nono campos.

ls -l | awk '{print $5, $9}'

1567 access.log
79 quoted.csv
207 sales.csv
85 scores-copy.txt
85 scores.txt
315 users.txt

Com NR > 1, a primeira linha sai e ficam só os tamanhos e nomes dos arquivos.

ls -l | awk 'NR > 1 {print $5, $9}'
1567 access.log
79 quoted.csv
207 sales.csv
85 scores-copy.txt
85 scores.txt
315 users.txt

4️⃣ awk BEGIN, END, somas e médias

  • ↪️ Variáveis e formatos de saída do printf

O bloco BEGIN roda uma vez antes de ler a primeira linha, e o bloco END uma vez depois de processar a última. Para uma soma, adicione a uma variável em cada linha e mostre-a em END. O diagrama abaixo mostra a ordem que o awk segue em cada linha ao somar os valores dos registros de vendas.

🔁 Ordem em que o awk processa sales.csv linha por linha
Diagrama explicativo
🔁 Ordem de processamento
$ awk -F, 'NR > 1 {t += $3 * $4} END {printf "total %.2f\n", t}' sales.csv
① Linha lidaNR = 1date,item,qty,priceNR = 22026-10-01,keyboard,2,45.00NR = 32026-10-01,mouse,5,19.90NR = 82026-10-04,monitor,2,189.00Sem mais linhas para lerA linha 8 é a última.
② Dividir campos (-F,)$1date$2item$3qty$4priceA linha de cabeçalho é dividida do mesmo jeito.$12026-10-01$2keyboard$32$445.00$3 quantidade, $4 preço unitário$12026-10-01$2mouse$35$419.90$3 quantidade, $4 preço unitário$12026-10-04$2monitor$32$4189.00$3 quantidade, $4 preço unitárioNenhuma linha para dividirO bloco END não lê linhas.
③ Padrão e açãoNR > 1 falsoA ação é pulada.t = (vazio)NR > 1 verdadeirot += 2 * 45.00t = 90NR > 1 verdadeirot += 5 * 19.90t = 189.5NR > 1 verdadeirot += 2 * 189.00t = 886.3END é executadototal 886.30O printf mostra t com duas casas decimais.
A primeira linha é o cabeçalho, então NR > 1 é falso e o awk passa para a linha seguinte sem executar a ação.
A partir da segunda linha o padrão é verdadeiro, e 90, a quantidade vezes o preço unitário, é somado à variável t.
A variável t mantém o valor de uma linha para outra, então a soma até a terceira linha é 189.5.
As linhas 4 a 7 seguem a mesma ordem, e até a última, a linha 8, t chega a 886.3.
Depois de processar a última linha, o bloco END roda uma vez e o printf mostra total 886.30.

A soma de todos os bytes enviados ($10) do log de acesso foi de 41298 bytes. Uma variável usada pela primeira vez começa vazia (0 como número), então não é preciso colocar 0 nela.

awk '{sum += $10} END {print sum}' access.log
41298

Se você mostrar a soma na ação de cada linha em vez de em END, cada linha mostra o total acumulado até ali. Ao mostrar o número da linha e t a cada soma da quantidade vezes o preço, saem sete linhas sem o cabeçalho, e o 886.3 da última linha é o total geral.

awk -F, 'NR > 1 {t += $3 * $4; print NR, t}' sales.csv
2 90
3 189.5
4 378.5
5 423.5
6 468.5
7 508.3
8 886.3

A média é calculada em END dividindo a soma pelo número de linhas. A soma das cinco pontuações foi 343 e a média, 68.6.

awk '{total += $3; n++} END {print total, n, total / n}' scores.txt
343 5 68.6

BEGIN serve para mostrar uma vez uma linha de cabeçalho acima dos resultados. Acima dos itens e valores (quantidade × preço unitário), a linha item total aparece uma só vez.

awk -F, 'BEGIN {print "item", "total"} NR > 1 {print $2, $3 * $4}' sales.csv
item total
keyboard 90
mouse 99.5
monitor 189
keyboard 45
cable 45
mouse 39.8
monitor 378

O separador de saída é trocado com a variável OFS em BEGIN. Com OFS como vírgula, entra uma vírgula em vez de um espaço no lugar das vírgulas de print, e a lista de contas sai em formato CSV.

awk 'BEGIN {FS = ":"; OFS = ","} {print $1, $3, $7}' users.txt
root,0,/bin/bash
bin,1,/sbin/nologin
daemon,2,/sbin/nologin
nobody,65534,/sbin/nologin
user,1000,/bin/bash
deploy,1001,/bin/bash
backup,1002,/sbin/nologin

Para alinhar colunas, use printf. %-10s é uma string alinhada à esquerda em 10 posições, %3d é um inteiro de 3 posições e %8.2f é um número em 8 posições com duas casas decimais.

awk -F, 'NR > 1 {printf "%-10s %8.2f\n", $2, $3, $3 * $4}' sales.csv
keyboard     2    90.00
mouse        5    99.50
monitor      1   189.00
keyboard     1    45.00
cable       10    45.00
mouse        2    39.80
monitor      2   378.00

Ao contrário de print, printf não muda de linha, então coloque [\n] no fim do formato. Sem [\n], os nomes dos itens saem emendados em uma linha.

awk -F, 'NR > 1 {printf "%s ", $2}' sales.csv
keyboard mouse monitor keyboard cable mouse monitor

5️⃣ Análise de logs e opções do comando awk

  • ↪️ Contagem de IPs e códigos de status, resumo das opções

🔲 Análise de logs

Somar em uma única variável dá um só total, então para contar por IP ou por código de status, reúna os valores em um array. n[$1]++ soma 1 à posição do array com o IP como chave, e o for (ip in n) de END tira as posições uma a uma.

awk '{n[$1]++} END {for (ip in n) print n[ip], ip}' access.log | sort -rn
4 192.0.2.10
3 203.0.113.25
3 198.51.100.7
2 192.0.2.44

A ordem em que for (ip in n) as tira não é definida (segundo o manual do GNU Awk), então ordenamos por número de requisições com sort -rn. 192.0.2.10 teve mais, com 4.

A quantidade por código de status é contada do mesmo jeito. Foram 3 respostas 404 e 1 resposta 500.

awk '{n[$9]++} END {for (s in n) print s, n[s]}' access.log | sort
200 6
301 1
304 1
404 3
500 1

Extraindo só os códigos de status e passando para sort e uniq -c, saem as mesmas quantidades.

awk '{print $9}' access.log | sort | uniq -c
      6 200
      1 301
      1 304
      3 404
      1 500

Para ver só as respostas de erro, coloque uma condição no código de status. As linhas de 400 ou mais foram três requisições procurando wp-login.php e .env e um erro 500.

awk '$9 >= 400 {print $9, $1, $7}' access.log
404 203.0.113.25 /wp-login.php
404 203.0.113.25 /wp-login.php
404 203.0.113.25 /.env
500 198.51.100.7 /api/search?q=awk

O total de bytes enviados por IP também é calculado somando em um array. 192.0.2.10 foi o que mais recebeu, com 31340 bytes.

awk '{b[$1] += $10} END {for (ip in b) print b[ip], ip}' access.log | sort -rn
31340 192.0.2.10
5120 192.0.2.44
4250 198.51.100.7
588 203.0.113.25

O campo de hora ($4) pode ser comparado como string. Entre linhas com a mesma data e formato, a ordem das strings é igual à ordem das horas, então selecionamos só as quatro requisições de 00:05 até antes de 00:10.

awk '$4 >= "[29/Oct/2026:00:05" && $4 < "[29/Oct/2026:00:10" {print $4, $7}' access.log
[29/Oct/2026:00:05:30 /contact.html
[29/Oct/2026:00:07:02 /old-page.html
[29/Oct/2026:00:07:15 /.env
[29/Oct/2026:00:09:48 /index.html

🔲 Opções do comando awk

📌 Principais opções: resultados deste artigo

OpçãoTarefaResultado neste artigo
-F fsDefine o separador de campos de entrada-F: separa o nome da conta ($1) e o shell de login ($7) de users.txt; -F, mostra o item e a quantidade de sales.csv junto com o cabeçalho (item qty)
-v var=valAtribui um valor a uma variável antes de o programa rodarPassar a variável de shell min com -v min=$min mostra seis linhas com 1000 bytes enviados ou mais; com -v FPAT=…, a coluna entre aspas de quoted.csv sai como um único campo
-i inplaceSalva a saída no arquivo original em vez da telaDepois de gawk -i inplace, nada aparece na tela e a cópia de scores.txt fica com duas colunas, nome e pontuação; com -v inplace::suffix=.bak, o conteúdo anterior fica em um arquivo .bak
--versionMostra as informações de versãoA primeira linha de [awk --version] mostra a versão GNU Awk 5

📎 Outras opções: segundo o manual oficial

OpçãoTarefa
-f program-fileLê o programa AWK de um arquivo em vez do primeiro argumento da linha de comando; -f pode ser indicado várias vezes
-e program-textUsa o texto da linha de comando como fonte do programa AWK; pode ser usado com funções de biblioteca carregadas por -f ou --include
-E fileParecido com -f, mas processado por último e bloqueia atribuições de variáveis na linha de comando; para scripts #!
--traditionalRoda em modo de compatibilidade, sem reconhecer as extensões GNU
--posixAtiva o modo de compatibilidade e adiciona restrições; por exemplo, não reconhece func, sinônimo de function
--lintAvisa sobre construções duvidosas ou difíceis de levar a outras implementações de AWK; com --lint=fatal, os avisos viram erros fatais
--dump-variablesGrava em um arquivo uma lista ordenada das variáveis globais com seus tipos e valores finais; awkvars.out se nenhum arquivo for indicado

🔲 Simulador do comando awk

No simulador abaixo, você pode digitar comandos awk nos mesmos arquivos de teste.

Simulador do comando awkGNU Awk 5
[root@server work]#
Um pequeno interpretador awk que funciona só no seu navegador. Os quatro arquivos de teste são os mesmos usados nas medições, e ↑↓ traz de volta os comandos anteriores.

🔢 FAQ & conteúdo recomendado

O shell não troca $min dentro de aspas simples, e ele chega ao awk como está, então passe-o com a opção -v. Se você colocar 1000 na variável de shell min e passar -v min=$min, saem as seis linhas com 1000 bytes enviados ou mais. Se você colocar o programa awk entre aspas duplas, o shell troca antes até o $1 de [print $1] por um valor vazio, e a linha inteira é mostrada.

Com -i inplace, o GNU Awk salva a saída no arquivo original em vez da tela. Ao executar com gawk -i inplace um programa que mostra o primeiro e o terceiro campos em uma cópia de scores.txt, nada apareceu na tela e o arquivo ficou com duas colunas, nome e pontuação. Como o arquivo original é sobrescrito direto, adicionar -v inplace::suffix=.bak mantém o conteúdo anterior em um arquivo .bak.

No servidor AlmaLinux 9, /usr/bin/awk era um link simbólico para gawk, e a primeira linha de [awk --version] mostrava a versão GNU Awk 5. Nesse servidor, os dois nomes executam o mesmo programa. Antes de usar recursos do GNU Awk como -i inplace ou FPAT, confirme com [awk --version] que é o GNU Awk.

ℹ️ Aviso de afiliados
O conteúdo deste site contém links de afiliados. Quando um visitante compra um produto ou serviço por meio de um desses links, o site recebe uma comissão do vendedor. O valor que o comprador paga (em promoções, ele diminui ↓) não aumenta por causa disso. Preços, descontos e informações de estoque valem para o momento em que o texto foi escrito e podem ter mudado, por isso confirme com o vendedor antes de comprar. Os produtos são escolhidos e avaliados por critérios próprios, e o recebimento de comissão não influencia a ordem de apresentação nem o conteúdo das avaliações.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Demonstre sua humanidade: 5   +   1   =