Comando awk: imprimir campos, delimitador -F e padrões condicionais
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
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.txtalice pass 82
bob fail 47
carol pass 91
dave pass 68
erin fail 55As 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.txtalice 82
bob 47
carol 91
dave 68
erin 55Se 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.txtalice82
bob47
carol91
dave68
erin55NR é 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.txt1 3 82
2 3 47
3 3 91
4 3 68
5 3 55O 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.
| Campo | Valor na primeira linha | Significado |
|---|---|---|
| $1 | 192.0.2.10 | IP do cliente |
| $4 | [29/Oct/2026:00:01:12 | Data e hora da requisição |
| $6 | "GET | Método da requisição (com aspas duplas na frente) |
| $7 | /index.html | URL da requisição |
| $9 | 200 | Código de status |
| $10 | 5120 | Bytes 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.log192.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 200Uma 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 -315 x86_64)"
15 x86_64)"
15 x86_64)"2️⃣ Definir o delimitador com awk -F
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.txtroot: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/nologinO 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.txtroot /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
nobody /sbin/nologin
user /bin/bash
deploy /bin/bash
backup /sbin/nologinArquivos 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.csvitem 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.csvitem
"cable
keyboardPara 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.csvitem
"cable, usb"
keyboardPara 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.txtroot bash
bin nologin
daemon nologin
nobody nologin
user bash
deploy bash
backup nologin3️⃣ Padrões condicionais do comando awk
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.log203.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 404Os 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.log203.0.113.25 /wp-login.php
203.0.113.25 /wp-login.php
203.0.113.25 /.envAo comparar com uma string, coloque o valor entre aspas duplas. Selecionamos só os nomes cujo segundo campo é pass.
awk '$2 == "pass" {print $1}' scores.txtalice
carol
daveA 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.txtnobody 65534
user 1000
deploy 1001
backup 1002Duas 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.txtuser /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.txtroot
user
deployawk -F: '$7 !~ /nologin/ {print $1, $7}' users.txtroot /bin/bash
user /bin/bash
deploy /bin/bashA 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.csvkeyboard 2
mouse 5
monitor 1
keyboard 1
cable 10
mouse 2
monitor 2A 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.txtCom 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.txt4️⃣ awk BEGIN, END, somas e médias
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.
$ awk -F, 'NR > 1 {t += $3 * $4} END {printf "total %.2f\n", t}' sales.csvA 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.log41298Se 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.csv2 90
3 189.5
4 378.5
5 423.5
6 468.5
7 508.3
8 886.3A 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.txt343 5 68.6BEGIN 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.csvitem total
keyboard 90
mouse 99.5
monitor 189
keyboard 45
cable 45
mouse 39.8
monitor 378O 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.txtroot,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/nologinPara 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.csvkeyboard 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.00Ao 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.csvkeyboard mouse monitor keyboard cable mouse monitor5️⃣ Análise de logs e opções do comando awk
🔲 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 -rn4 192.0.2.10
3 203.0.113.25
3 198.51.100.7
2 192.0.2.44A 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 | sort200 6
301 1
304 1
404 3
500 1Extraindo 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 500Para 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.log404 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=awkO 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 -rn31340 192.0.2.10
5120 192.0.2.44
4250 198.51.100.7
588 203.0.113.25O 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ção | Tarefa | Resultado neste artigo |
|---|---|---|
| -F fs | Define 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=val | Atribui um valor a uma variável antes de o programa rodar | Passar 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 inplace | Salva a saída no arquivo original em vez da tela | Depois 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 |
| --version | Mostra as informações de versão | A primeira linha de [awk --version] mostra a versão GNU Awk 5 |
📎 Outras opções: segundo o manual oficial
| Opção | Tarefa |
|---|---|
| -f program-file | Lê o programa AWK de um arquivo em vez do primeiro argumento da linha de comando; -f pode ser indicado várias vezes |
| -e program-text | Usa 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 file | Parecido com -f, mas processado por último e bloqueia atribuições de variáveis na linha de comando; para scripts #! |
| --traditional | Roda em modo de compatibilidade, sem reconhecer as extensões GNU |
| --posix | Ativa o modo de compatibilidade e adiciona restrições; por exemplo, não reconhece func, sinônimo de function |
| --lint | Avisa sobre construções duvidosas ou difíceis de levar a outras implementações de AWK; com --lint=fatal, os avisos viram erros fatais |
| --dump-variables | Grava 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.
🔢 FAQ & conteúdo recomendado
Ordenação
Comando sort do Linux: ordenar arquivos
O comando sort ordena o conteúdo de um arquivo por ordem alfabética ou numérica. Use-o em seguida para ver os totais do awk do maior para o menor.
Remoção de duplicatas
Comando uniq do Linux
O comando uniq reduz a uma só as linhas iguais seguidas e, com -c, conta quantas vezes se repetiram.
Visualização de arquivos
Comandos head e tail do Linux
Os comandos head e tail mostram só as primeiras ou últimas linhas de um arquivo. São muito usados para conferir o log de acesso de um servidor.
ℹ️ 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.