0Pricing
Linux Command Line & Bash Scripting Mastery · Aula

Registros, campos e separadores personalizados no awk

Controle os separadores de campos de entrada e saída para dividir linhas de CSV, TSV e registros em colunas organizadas.

Registros, campos e separadores personalizados no awk é uma aula grátis de Linux Command Line & Bash Scripting Mastery no CoddyKit. Esta é a aula 1 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Linux Command Line & Bash Scripting Mastery, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Linux Command Line & Bash Scripting Mastery inclui 4 aulas no total.

O que são registros e campos no awk

awk lê a entrada linha por linha. Cada linha é chamada de registro, e cada trecho separado por espaços em branco dentro dessa linha é chamado de campo.

  • $0 — o registro atual inteiro (a linha completa)
  • $1 — o primeiro campo
  • $2 — o segundo campo
  • $NF — o último campo (NF = número de campos)

Por padrão, awk separa os campos em qualquer sequência de espaços em branco (espaços ou tabulações). Isso o torna imediatamente útil para analisar registros, a saída de comandos e dados delimitados por espaços.

#!/usr/bin/env bash
# Show how awk sees records and fields
echo 'alice 30 engineer' | awk '{ print "Name:", $1, "Age:", $2, "Role:", $3 }'

# $NF is always the last field — regardless of how many there are
echo 'one two three four five' | awk '{ print "Last field:", $NF }'

O separador de campos de entrada: FS

A variável integrada FS (separador de campos) informa ao awk como dividir cada registro em campos. Seu valor padrão é um único espaço, o que ativa o modo de divisão por espaços em branco.

É possível definir FS de duas formas:

  • Com a opção -F na linha de comando: awk -F':'
  • Dentro de um bloco BEGIN: BEGIN { FS = ":" }

As duas formas são equivalentes. A abordagem com o bloco BEGIN é preferível em scripts mais longos, pois mantém a configuração dentro do próprio script, tornando-o mais legível e portável.

#!/usr/bin/env bash
# Parse /etc/passwd using ':' as the field separator
# Field 1 = username, field 3 = UID, field 7 = shell
echo 'root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin' \
  | awk -F':' '{ print $1, "UID="$3, "shell="$7 }'

Definindo FS no bloco BEGIN

Para scripts mais longos que uma única linha, colocar FS dentro de um bloco BEGIN é a prática padrão. O bloco BEGIN é executado antes de o awk ler qualquer entrada, portanto o separador está pronto para o primeiro registro.

Esse padrão também permite definir várias variáveis de uma vez, adicionar comentários e manter sua lógica autocontida em um arquivo de script.

Separadores comuns que encontrará na prática:

  • Dois-pontos : — /etc/passwd, /etc/shadow
  • Tabulação \t — exportações TSV, saída de compiladores
  • Vírgula , — arquivos CSV (simples, sem campos entre aspas)
  • Barra vertical | — alguns formatos de registros, despejos de bancos de dados
#!/usr/bin/env bash
# awk script using BEGIN to set FS for TSV input
printf 'alice\t30\tengineer\nbob\t25\tdesigner\ncarol\t35\tmanager\n' \
  | awk 'BEGIN { FS = "\t" } { printf "%-10s age=%-3s role=%s\n", $1, $2, $3 }'

Analisando arquivos CSV com awk

CSV (valores separados por vírgulas) é um dos formatos de dados mais comuns na engenharia de shell. Definir FS="," faz o awk tratar as vírgulas como delimitadores.

Advertência importante: o tratamento integrado de CSV do awk não considera campos entre aspas que contenham vírgulas (por exemplo, "Smith, John"). Para CSVs simples, sem vírgulas entre aspas, isso funciona perfeitamente. Para CSVs compatíveis com a RFC 4180 e com campos entre aspas, use um analisador de CSV apropriado ou miller/csvkit.

Uma tarefa comum no mundo real é extrair colunas específicas e filtrar linhas por valor — ambas são triviais com awk depois que FS é definido.

#!/usr/bin/env bash
# Simple CSV: extract name and salary columns, filter salary > 50000
data='name,department,salary
alice,engineering,95000
bob,marketing,48000
carol,engineering,112000
dave,hr,45000'

echo "$data" | awk -F',' '
  NR == 1 { next }          # skip header row
  $3 > 50000 { print $1, "earns", $3 }
'

Separadores de campos com vários caracteres e expressões regulares

O FS do awk não se limita a um único caractere — ele pode ser uma expressão regular. Isso é útil para formatos reais de registros nos quais os campos são separados por delimitadores de comprimento variável.

Exemplos de separadores com expressões regulares:

  • FS = "[,;]" — divide pela vírgula ou pelo ponto e vírgula
  • FS = "[ \t]+" — divide por um ou mais espaços ou tabulações (igual ao padrão, mas de forma explícita)
  • FS = "::" — divide por dois-pontos duplos literais
  • FS = "\\|" — divide pelo caractere de barra vertical (é necessário escapar o caractere)

Quando FS é uma expressão regular, o awk (gawk) a trata como um padrão, não como uma cadeia de caracteres literal.

#!/usr/bin/env bash
# Log lines with mixed delimiters: split on " | " or "::" or ","
# Here we split on one or more spaces or pipe characters
printf '2024-01-15 | ERROR | disk full | /dev/sda1\n2024-01-15 | INFO  | startup ok | main\n' \
  | awk -F' \\| ' '{ printf "date=%-12s level=%-6s msg=%s\n", $1, $2, $3 }'

# Split on multiple possible delimiters using character class
echo 'alpha,beta;gamma,delta;epsilon' \
  | awk -F'[,;]' '{ for(i=1; i<=NF; i++) print i": "$i }'

O separador de campos de saída: OFS

OFS (separador de campos de saída) controla o que o awk coloca entre os campos quando reconstrói um registro com print. Seu padrão é um único espaço.

A ideia principal: OFS só é inserido entre campos quando se usa a sintaxe com vírgula em print ou quando se atribui um valor a um campo e o awk reconstrói $0. Se concatenar usando espaços no código-fonte, OFS não será usado.

  • print $1, $2, $3 — as vírgulas acionam OFS entre os campos
  • print $1 " " $2 — espaço explícito; OFS é ignorado

Um padrão comum: ler CSV, transformar e gravar TSV definindo FS="," e OFS="\t".

#!/usr/bin/env bash
# Convert CSV to TSV using FS and OFS
data='alice,30,engineer
bob,25,designer
carol,35,manager'

echo "$data" | awk 'BEGIN { FS=","; OFS="\t" } { print $1, $2, $3 }'

echo '---'

# OFS also applies when you modify a field — awk rebuilds $0 with OFS
echo 'alice,30,engineer' | awk 'BEGIN { FS=","; OFS=" | " } { $1=$1; print $0 }'

Forçando o awk a reconstruir $0 com OFS

Há um truque sutil, mas importante: atribuir um valor a qualquer campo (até atribuir um campo a si mesmo, $1=$1) força o awk a reconstruir $0, juntando todos os campos com OFS.

Esta é a forma idiomática de reformar os delimitadores de um registro sem imprimir manualmente todos os campos:

  • Defina FS como o delimitador de entrada
  • Defina OFS como o delimitador de saída desejado
  • Acione a reconstrução com $1=$1
  • Imprima $0

Essa abordagem funciona com qualquer quantidade de campos e evita codificar diretamente $1, $2, $3, ....

#!/usr/bin/env bash
# Reformat a pipe-delimited file to comma-separated WITHOUT listing every field
printf 'alice|30|engineer|london\nbob|25|designer|paris\ncarol|35|manager|berlin\n' \
  | awk 'BEGIN { FS="|"; OFS="," } { $1=$1; print $0 }'

# Useful when you don't know how many fields there are:
printf 'a|b|c|d|e|f|g\n1|2|3|4|5|6|7\n' \
  | awk 'BEGIN { FS="|"; OFS="\t" } { $1=$1; print $0 }'

O separador de registros: RS

Assim como FS divide os campos dentro de um registro, RS (separador de registros) define o que separa os registros uns dos outros. Por padrão, RS é um newline, portanto o awk processa uma linha por vez.

Alterar RS permite realizar um processamento poderoso de registros com várias linhas:

  • RS="" — modo de parágrafos: linhas em branco separam os registros (os campos podem ocupar várias linhas)
  • RS=";" — dividir nos pontos e vírgulas (útil para despejos de SQL)
  • RS="\n" — newline explícito (o padrão)

No modo de parágrafos (RS=""), FS continua sendo usado para dividir os campos dentro do registro com várias linhas, e os newline dentro de um registro também são tratados automaticamente como separadores de campos.

#!/usr/bin/env bash
# Paragraph mode: each blank-line-separated block is one record
# Useful for processing structured text blocks (e.g., stanzas, config sections)
data='Name: Alice
Role: Engineer
City: London

Name: Bob
Role: Designer
City: Paris'

echo "$data" | awk 'BEGIN { RS=""; FS="\n" } {
  print "Record", NR":"
  for (i=1; i<=NF; i++) print "  ", $i
  print ""
}'

O separador de registros de saída: ORS

ORS (separador de registros de saída) é impresso após cada instrução print. Por padrão, ele é um newline (\n), e é por isso que cada print vai para uma nova linha.

Alterar ORS permite:

  • Unir registros em uma única linha: ORS=" "
  • Adicionar linhas em branco entre os registros de saída: ORS="\n\n"
  • Criar formatos de saída personalizados, como fragmentos de JSON ou XML

Observe que printf não usa ORS — ele se aplica somente à instrução print simples. Use printf quando precisar de controle total sobre a formatação.

#!/usr/bin/env bash
# Join all matching lines onto one line by setting ORS to a space
printf 'apple\nbanana\ncherry\ndate\n' | awk '{ ORS=" " } { print $0 }'
echo  # final newline

# Add a blank line after every output record for readability
printf 'alice 30 engineer\nbob 25 designer\ncarol 35 manager\n' \
  | awk 'BEGIN { ORS="\n\n" } { print $1, "is a", $3 }'

Exemplo prático: analisar registros de acesso do Apache

Os registros de acesso do Apache/nginx têm um formato conhecido, com campos delimitados por espaços. Alguns campos (como o carimbo de data e hora) contêm espaços e são colocados entre colchetes ou aspas, o que dificulta a divisão direta em campos pelo awk.

Uma abordagem prática é usar um FS de expressão regular que leve a estrutura em consideração ou extrair campos específicos por posição, conhecendo o formato exato.

Os campos do formato de registro combinado são, aproximadamente:

  1. IP do cliente
  2. Identificação (geralmente -)
  3. Usuário autenticado (geralmente -)
  4. Carimbo de data e hora (entre colchetes, conta como um único token)
  5. Método+caminho+protocolo da solicitação (entre aspas)
  6. Código de status HTTP
  7. Bytes da resposta
#!/usr/bin/env bash
# Parse a simulated Apache Combined Log Format line
# Extract: IP, status code, bytes, and request path
logs='192.168.1.10 - alice [15/Jan/2024:10:23:45 +0000] "GET /api/users HTTP/1.1" 200 1523
10.0.0.5 - - [15/Jan/2024:10:23:46 +0000] "POST /login HTTP/1.1" 401 89
172.16.0.3 - bob [15/Jan/2024:10:23:47 +0000] "GET /dashboard HTTP/1.1" 200 8741'

echo "$logs" | awk '{
  ip     = $1
  status = $9
  bytes  = $10
  # Extract the request path from the quoted string in field 7
  split($7, parts, "/")
  path = "/" parts[2]
  printf "ip=%-15s status=%s bytes=%-6s endpoint=%s\n", ip, status, bytes, path
}'

Combinando FS, OFS, RS e ORS em um pipeline

Na engenharia real de shell, raramente se usam esses separadores isoladamente. Um padrão comum de pipeline é usar o awk como um conversor de formatos no meio de um pipeline, transformando um formato estruturado em outro.

Principais pontos sobre a combinação de separadores:

  • Defina sempre FS e OFS juntos em BEGIN ao converter formatos
  • Use $1=$1 para disparar a reconstrução de $0 quando quiser reformular todos os campos sem listá-los
  • Altere RS somente quando seus registros realmente ocuparem várias linhas
  • Use ORS para controlar o espaçamento entre os registros de saída
  • Prefira printf para uma formatação precisa; use print quando a terminação automática de ORS for conveniente
#!/usr/bin/env bash
# Full pipeline: read a colon-delimited file,
# filter rows where field 3 (UID) >= 1000 (real users),
# then output as tab-separated: username, UID, home dir
echo 'root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
alice:x:1001:1001:Alice:/home/alice:/bin/bash
bob:x:1002:1002:Bob:/home/bob:/bin/zsh
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin' \
  | awk 'BEGIN { FS=":"; OFS="\t" } $3 >= 1000 { print $1, $3, $6 }'

Verificação de conhecimento: OFS e reconstrução de campos

Teste sua compreensão de como OFS interage com a atribuição de campos no awk.

Recapitulação da lição: registros, campos e separadores

Agora você tem controle total sobre como o awk lê e grava dados estruturados. Veja um resumo das quatro variáveis de separadores:

  • FS — separador de campos de entrada. Definido com -F ou em BEGIN. Pode ser um caractere, uma string ou uma expressão regular. Padrão: espaços em branco.
  • OFS — separador de campos de saída. Inserido entre os campos nas chamadas print $1, $2 e quando o awk reconstrói $0 após uma atribuição de campo. Padrão: um único espaço.
  • RS — separador de registros de entrada. Define o que separa os registros (linhas). Padrão: newline. Defina-o como uma string vazia para usar o modo de parágrafos.
  • ORS — separador de registros de saída. Adicionado ao final de cada print. Padrão: newline. Altere-o para unir linhas ou adicionar espaçamento.

O padrão mais importante a memorizar é: defina FS e OFS em BEGIN e use $1=$1 para reconstruir $0 sempre que quiser reformular os delimitadores em todos os campos sem codificar posições de campos explicitamente. Esse padrão funciona com arquivos que tenham qualquer número de colunas e é a base dos pipelines de conversão de formatos com awk.

Perguntas Frequentes

A aula “Registros, campos e separadores personalizados no awk” é grátis?

Sim — o texto completo de “Registros, campos e separadores personalizados no awk” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Linux Command Line & Bash Scripting Mastery, atualize para CoddyKit PRO. O curso de Linux Command Line & Bash Scripting Mastery inclui 4 aulas no total.

O que vou aprender em “Registros, campos e separadores personalizados no awk”?

Controle os separadores de campos de entrada e saída para dividir linhas de CSV, TSV e registros em colunas organizadas. Você pratica Linux Command Line & Bash Scripting Mastery com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Linux Command Line & Bash Scripting Mastery?

Nenhuma experiência prévia é necessária. Linux Command Line & Bash Scripting Mastery no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 4.

Quanto tempo leva a aula “Registros, campos e separadores personalizados no awk”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Linux Command Line & Bash Scripting Mastery?

Sim. Cada aula de Linux Command Line & Bash Scripting Mastery inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Registros, campos e separadores personalizados no awk
  2. Padrões, intervalos e blocos BEGIN/END
  3. Agregação com matrizes e agrupamento no awk
  4. Funções do awk, formatação com printf e geração de relatórios
← Voltar para Linux Command Line & Bash Scripting Mastery