Linux: Os Três Mosqueteiros do Processamento de Texto
Se o grep serve para "encontrar", então awk, sed e cut servem para "mudar". cut fatia colunas, awk gera relatórios de dados, sed faz substituições em massa — juntos com pipes, eles dão conta de praticamente qualquer tarefa de texto.
📋 Pré-requisitos: Você já deve conhecer
- Aula 14: Busca em Texto
1. O Que Você Vai Aprender
- cut: extrair colunas por delimitador
- awk: processamento avançado de colunas
- sed: substituir e deletar
- tr: tradução de caracteres
- diff: comparação de arquivos
2. A História de Processar um Arquivo CSV
(1) O Problema: Arquivo CSV Precisa de Conversão de Formato
Alex recebeu um arquivo CSV e precisava extrair as colunas 2 e 5, remover linhas em branco e mudar o delimitador de vírgulas para tabulações.
(2) Uma Cadeia de Pipeline Faz Tudo
cat data.csv | cut -d',' -f2,5 | sed '/^$/d' | tr ',' '\t' > output.tsv
cut -d',' -f2,5: divide por vírgula, pega colunas 2 e 5sed '/^$/d': deleta linhas em brancotr ',' '\t': substitui vírgulas por tabulações> output.tsv: grava em um novo arquivo
(3) O Benefício: Processamento de Dados Sem Programar
Alex pulou a trabalheira de abrir o Excel ou escrever um script Python. Um comando, dados processados.
3. Pontos-Chave
(1) cut — Fatiar por Coluna
# Dividir por delimitador
cut -d',' -f1,3 arquivo.csv # Delimitador vírgula, pega colunas 1 e 3
cut -d: -f1 /etc/passwd # Delimitador dois-pontos, pega nomes de usuário
ℹ️ Nota:
cuté adequado para extração simples de colunas (delimitador fixo, números de coluna fixos). Para cenários que exigem filtragem condicional, cálculo ou formatação, useawkem vez disso. Por exemplo,awk -F: '$3 >= 1000 {print $1}' /etc/passwdpode filtrar usuários com UID ≥ 1000 —cutnão consegue fazer isso.
# Dividir por posição de caractere
cut -c1-5 arquivo.txt # Pega caracteres 1-5
cut -c1,3,5 arquivo.txt # Pega caracteres 1, 3 e 5
(2) awk — Gerador de Relatórios de Dados
awk é uma linguagem completa de processamento de texto. Seu padrão central é:
awk 'padrão {ação}' arquivo
Variáveis embutidas do awk:
| Variável | Significado |
|---|---|
$0 |
Linha inteira |
$1 |
Primeiro campo |
$2 |
Segundo campo |
NF |
Número de campos |
NR |
Número da linha |
FS |
Separador de campos de entrada (padrão: espaço/tab) |
OFS |
Separador de campos de saída (padrão: espaço) |
$0 é a linha inteira, $1/$2/$3 são os campos 1/2/3, NR é o número da linha, NF é a quantidade de campos ($NF é o último campo). Com -F: para especificar um delimitador, dá para resolver a maior parte das tarefas de extração de texto.
# Uso básico
awk '{print $1}' arquivo.txt # Imprime coluna 1
awk '{print $1, $3}' arquivo.txt # Imprime colunas 1 e 3
awk '{print NR, $0}' arquivo.txt # Imprime número da linha e linha inteira
awk '{print $NF}' arquivo.txt # Imprime a última coluna
awk -F: '{print $1}' /etc/passwd # Especifica dois-pontos como delimitador
# Correspondência de padrão
awk '/erro/ {print}' log.txt # Processa apenas linhas que contêm erro
awk '$3 > 100 {print $1, $3}' dados.txt # Saída apenas quando coluna 3 > 100
# Agregação
awk '{soma += $1} END {print soma}' numeros.txt # Soma
awk '{cont++} END {print cont}' arquivo.txt # Contar
(3) sed — Editor de Stream
# Substituir
sed 's/antigo/novo/' arquivo.txt # Substitui a primeira ocorrência por linha
sed 's/antigo/novo/g' arquivo.txt # Substituição global
sed 's/antigo/novo/2' arquivo.txt # Substitui apenas a 2ª ocorrência por linha
sed 's/antigo/novo/g' arquivo.txt > novo.txt # Grava em novo arquivo
sed -i 's/antigo/novo/g' arquivo.txt # Edição no local (modifica o arquivo diretamente)
sed -i.bak 's/antigo/novo/g' arquivo.txt # Faz backup do original como arquivo.txt.bak
sed -i modifica o arquivo no local sem desfazer. Visualize o resultado primeiro sem -i: sed 's/antigo/novo/g' arquivo.txt, depois adicione -i depois de confirmar. Ou use sed -i.bak para criar um backup automaticamente.
# Deletar
sed '/padrão/d' arquivo.txt # Deleta linhas que correspondem ao padrão
sed '3d' arquivo.txt # Deleta a linha 3
sed '5,10d' arquivo.txt # Deleta as linhas 5-10
sed '/^$/d' arquivo.txt # Deleta linhas em branco
# Imprimir
sed -n '5,10p' arquivo.txt # Imprime apenas as linhas 5-10
sed -n '/padrão/p' arquivo.txt # Imprime apenas linhas que correspondem
(4) tr — Tradução de Caracteres
# Conversão de maiúsculas/minúsculas
echo "olá" | tr 'a-z' 'A-Z' # OLÁ
cat arquivo.txt | tr '[:lower:]' '[:upper:]'
# Substituir e deletar
echo "a,b,c" | tr ',' ' ' # a b c
echo "olá mundo" | tr -s ' ' # olá mundo (comprime espaços repetidos)
echo "olá123" | tr -d '0-9' # olá (deleta dígitos)
echo "abc123" | tr -d '[:digit:]' # abc (deleta dígitos)
# Conversão de fim de linha (Windows ↔ Unix)
tr -d '\r' < win.txt > unix.txt # Remove o CR do Windows
tr '\n' ',' < lista.txt # Substitui quebras de linha por vírgulas
(5) diff — Comparação de Arquivos
diff arquivo1.txt arquivo2.txt # Comparação básica
diff -u arquivo1.txt arquivo2.txt # Formato unificado (mais legível)
diff -i arquivo1.txt arquivo2.txt # Ignora diferenças de maiúsculas/minúsculas
diff -w arquivo1.txt arquivo2.txt # Ignora diferenças de espaços em branco
diff -r dir1/ dir2/ # Comparação recursiva de diretórios
(6) ▶ Exemplo: cut — Fatiar Colunas
# Extrair nome de usuário e shell de /etc/passwd
cut -d: -f1,7 /etc/passwd | head -5
# root:/bin/bash
# daemon:/usr/sbin/nologin
# bin:/usr/sbin/nologin
# Pegar coluna 5 (tamanho do arquivo) da saída de ls -l
ls -la | tr -s ' ' | cut -d' ' -f5 | head -5
Saída:
TEXTroot:/bin/bash daemon:/usr/sbin/nologin bin:/usr/sbin/nologin sys:/usr/sbin/nologin sync:/usr/sbin/nologin 4096 4096 1234 5678 910
(7) ▶ Exemplo: awk — Processamento de Colunas
# Imprimir nome de usuário e diretório home
awk -F: '{print $1, "Home:", $6}' /etc/passwd | head -5
# Encontrar usuários regulares com UID maior que 1000
awk -F: '$3 >= 1000 {print $1, "(UID:" $3 ")"}' /etc/passwd
# Calcular tamanho total de arquivos
ls -la | grep "^-" | awk '{soma += $5} END {print "Total:", soma/1024/1024, "MB"}'
# Saída formatada (printf)
ls -la | awk '{printf "%-20s %8s\n", $9, $5}'
Saída:
TEXTroot Home: /root daemon Home: /usr/sbin bin Home: /bin sys Home: /dev nobody Home: /nonexistent alice (UID:1000) bob (UID:1001) Total: 256.5 MB .bashrc 3771 .profile 220 .bash_history 1234
(8) ▶ Exemplo: sed — Substituição em Massa
# Substituir localhost por 127.0.0.1 no arquivo
sed -i 's/localhost/127.0.0.1/g' config.txt
# Comentar linhas que começam com listen no arquivo de configuração
sed -i '/^listen/s/^/#/' nginx.conf
# Inserir uma nova linha após a linha 2
sed '2a\Nova linha inserida' arquivo.txt
# Extrair timestamps de um arquivo de log
sed -n 's/.*\[\(.*\)\].*/\1/p' access.log | head -5
Saída:
TEXT07/Jul/2026:10:15:30 +0000 07/Jul/2026:10:15:31 +0000 07/Jul/2026:10:15:32 +0000 07/Jul/2026:10:15:33 +0000 07/Jul/2026:10:15:34 +0000
(9) ▶ Exemplo: tr — Tradução de Caracteres
# Contar palavras em um texto
cat arquivo.txt | tr -s ' ' '\n' | sort | uniq -c | sort -rn | head -10
# Converter uma lista em uma única linha separada por vírgulas
cat lista.txt | tr '\n' ',' | sed 's/,$//'
# Remover todos os comentários e linhas em branco de um arquivo de configuração
grep -v "^#" config.txt | grep -v "^$" | tr -s '\n'
Saída:
TEXT42 o 28 e 25 linux 20 arquivo 18 comando 15 usuario 12 sistema 10 processo 8 diretorio 6 shell maca,banana,cereja,damasco ServerName localhost Listen 80 DocumentRoot /var/www/html ErrorLog /var/log/apache2/error.log
(10) ▶ Exemplo: diff — Comparação de Arquivos
# Criar duas versões
echo -e "maca\nbanana\nlaranja" > v1.txt
echo -e "maca\nmirtilo\nlaranja" > v2.txt
# Comparar
diff -u v1.txt v2.txt
# --- v1.txt
# +++ v2.txt
# @@ -1,3 +1,3 @@
# maca
# -banana
# +mirtilo
# laranja
(11) ▶ Exemplo Abrangente: Relatório de Monitoramento do Sistema
#!/bin/bash
# sys-report.sh - Gera relatório de monitoramento do sistema
echo "========================================="
echo " Relatório de Monitoramento do Sistema"
echo " Gerado em: $(date)"
echo "========================================="
echo ""
echo "1. Top 5 Processos por Uso de CPU"
ps aux --sort=-%cpu | head -6 | awk '{printf "%-10s %-5s %-5s %s\n", $1, $2, $3, $11}'
echo ""
echo "2. Uso de Disco"
df -h | grep "^/" | awk '{printf "%-20s %5s %5s %5s\n", $6, $2, $3, $5}'
echo ""
echo "3. Top 5 por Uso de Memória"
ps aux --sort=-%mem | head -6 | awk '{printf "%-10s %-5s %-5s %s\n", $1, $2, $4, $11}'
echo ""
echo "4. Contagem de Erros em /var/log"
grep -ric "erro" /var/log/*.log 2>/dev/null | grep -v ":0" | head -10
echo ""
echo "5. Portas em Escuta"
ss -tlnp | tail -n +2 | awk '{print $4, $1}' | sed 's/.*://'
echo ""
echo "========================================="
❓ Perguntas Frequentes
P: O que torna o awk mais poderoso que o cut? R: O cut só consegue fazer fatiamento simples de colunas (delimitador fixo). O awk suporta filtragem condicional, cálculos e saída formatada. O awk é uma linguagem de programação completa — suporta variáveis, arrays, loops e funções. Use cut para cenários simples, awk para complexos.
P:
sed -ié arriscado para modificar o arquivo original? R: Sim —sed -imodifica o arquivo no local sem desfazer. Visualize sem-iprimeiro, ou usesed -i.bakpara criar um backup automaticamente. Depois de confirmar o resultado, você pode excluir o arquivo.bak.
P: Qual é a diferença entre diff e vimdiff? R: diff é uma ferramenta de linha de comando que gera resultados de comparação em texto. vimdiff é o modo de comparação visual do vim, com tela dividida lado a lado e edição interativa. Use diff para comparações rápidas, vimdiff para comparações complexas.
P: O tr consegue lidar com caracteres chineses? R: Consegue, mas com cautela. Caracteres chineses são codificados em UTF-8 multibyte, e o tr processa por byte, o que pode quebrar caracteres chineses. Para texto em chinês, use
sedou Python em vez disso.
P: Como combinar vários comandos de processamento de texto com mais eficiência? R: O princípio é "uma passagem, várias operações". Coloque a filtragem simples (grep) primeiro para reduzir o volume de dados, depois o processamento mais pesado depois. Evite criar muitos pipes intermediários em
cat arquivo | grep | awk | sed | ....
📖 Resumo
cut -d',' -f1,3fatia colunas por delimitadorawk '{print $1}'extrai colunas,-F:define o delimitador,/padrão/corresponde,ENDexecuta no finalsed 's/antigo/novo/g'substituição global,-iedição no local,/^$/ddeleta linhas em brancotr 'a-z' 'A-Z'conversão de maiúsculas/minúsculas,-ddeleta,-scomprime repetiçõesdiff -u arquivo1 arquivo2compara diferenças entre arquivos
📝 Exercícios
- Básico (Dificuldade ⭐): Use cut para extrair nomes de usuário, UIDs (coluna 3) e shells de login de
/etc/passwd, depois use tr para converter o conteúdo de/etc/hostnamepara maiúsculas - Intermediário (Dificuldade ⭐⭐): Use awk para filtrar arquivos maiores que 1MB da saída de
ls -l, depois use sed para substituir em lote um número de porta (8080 → 9090) em um arquivo de configuração, criando um backup do original - Avançado (Dificuldade ⭐⭐⭐): Crie dois arquivos de configuração ligeiramente diferentes, use
diff -upara ver as diferenças, depois escreva uma cadeia de pipeline para extrair todas as linhas de erro de um arquivo de log, contar erros por hora e exibir as 5 horas de pico