Linux: Pipes e Filtros — A Essência da Filosofia Unix

O núcleo da filosofia Unix é "faça uma coisa bem feita". O pipe | encadeia esses pequenos programas — a saída de um se torna a entrada do próximo.

📋 Pré-requisitos: Você deve primeiro concluir

1. O Que Você Vai Aprender


2. A História de um Arquivo de Log de 10GB

(1) O Problema: Logs Grandes Demais Para Navegar Manualmente

Alex precisava encontrar os 10 IPs mais frequentes em um log de acesso do Nginx de 10GB. Abrir em um editor era impossível (10GB não abre) e escrever um script Python era exagero.

(2) O Poder de um Pipeline de Uma Linha

Bob ensinou-lhe a combinar comandos com pipes:

BASH
cat access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -10

ℹ️ Nota: cat file | command é comum, mas o cat aqui apenas passa o conteúdo do arquivo para o pipe — usar command < file ou awk '{...}' file diretamente é mais eficiente, economizando um processo. Isso é chamado "UUOC" (Useless Use of Cat); embora funcione bem, pode ser otimizado para desempenho.

Saída:

TEXT
 45231 192.168.1.100
 38902 10.0.0.45
 21045 192.168.1.200

(3) O Benefício: Tarefas Complexas em Um Comando

Alex descobriu que combinações de pipelines podem lidar com praticamente qualquer tarefa de extração de dados — contagem, filtragem, ordenação, ranking, deduplicação. Um único comando é um mini pipeline de processamento de dados.


3. Pontos-Chave

(1) Como os Pipes Funcionam

TEXT

comando1 | comando2 | comando3
    │           │           │
    │   saída   │   saída   │
    └──────────→│──────────→│──────────→ Saída final
                │           │
           stdout do comando1 conecta ao stdin do comando2
💡 Dica: Os pipes funcionam conectando o stdout do comando anterior ao stdin do próximo comando — os dados fluem através de buffers do kernel sem serem gravados no disco. Isso significa que comandos em um pipeline rodam em paralelo, e processar arquivos grandes não esgota a memória.

(2) Filtros Comuns

Comando Finalidade Opções comuns
sort Ordenar -n numérico, -r reverso, -k por coluna, -u ordena e deduplica
uniq Deduplicar (adjacentes) -c contar, -d mostrar só duplicados, -u mostrar só únicos
wc Contar -l linhas, -w palavras, -c caracteres
head Mostrar início -n 10 primeiras 10 linhas, -c 100 primeiros 100 caracteres
tail Mostrar fim -n 10 últimas 10 linhas, -f seguir em tempo real
tee Dividir stream Saída para arquivo e tela ao mesmo tempo
💡 Dica: tee recebeu esse nome por causa da "junção em T" da hidráulica — ele divide os dados do pipeline em dois, passando uma cópia adiante e gravando outra em um arquivo. Ao depurar um pipeline, insira tee /tmp/debug.txt no meio para capturar resultados intermediários sem afetar a saída final.

| nl | Numerar linhas | -ba numerar todas as linhas |

(3) ▶ Exemplo: Contar Informações de Arquivos

BASH
# Contar o número de arquivos
ls -la | wc -l
# Nota: wc -l inclui a linha "total", então o número real de arquivos é um a menos

# Contar o total de linhas em todos os arquivos .md
cat *.md | wc -l

# Mostrar o uso de disco do diretório atual
ls -lh | tail -n +2 | awk '{print $5, $9}'

Saída:

TEXT
15
342
4.0K config.yml
12M data.tar.gz

(4) ▶ Exemplo: Ordenação e Deduplicação

TEXT
# Ordenar endereços IP (alfabético vs numérico)
cat << EOF | sort
192.168.1.100
10.0.0.45
192.168.1.200
10.0.0.2
EOF

# sort -n para ordenação numérica (por segmento do IP)
cat << EOF | sort -t. -k1,1n -k2,2n -k3,3n -k4,4n
192.168.1.100
10.0.0.45
192.168.1.200
10.0.0.2
EOF

# Deduplicar e contar
cat << EOF | sort | uniq -c | sort -rn
apple
banana
apple
orange
banana
apple
EOF

Saída:

TEXT
10.0.0.2
10.0.0.45
192.168.1.100
192.168.1.200
      3 apple
      2 banana
      1 orange

(5) ▶ Exemplo: head e tail

BASH
# Ver as 5 primeiras linhas
ls -la /etc | head -5

# Ver as 5 últimas linhas
ls -la /etc | tail -5

# Mostrar linhas 10-20
cat arquivo-longo.txt | head -20 | tail -11

# Acompanhar um log em tempo real (pressione Ctrl+C para sair)
tail -f /var/log/syslog

# Ver as últimas 10 entradas de log
tail -f -n 10 /var/log/syslog

Saída:

TEXT
total 72
drwxr-xr-x   2 root root 4096 Jul  7 10:00 bin
drwxr-xr-x   3 root root 4096 Jul  7 10:00 lib
drwxrwxrwt  15 root root 4096 Jul  7 10:30 tmp
BASH
# Ver resultados na tela e salvar em arquivo ao mesmo tempo
ls -la | tee saida.txt

# Modo anexar
echo "Novo conteúdo" | tee -a saida.txt

# Salvar resultados intermediários do pipeline
ps aux | tee processos.txt | grep nginx
# Primeiro salva todos os processos com tee, depois filtra por nginx

Saída:

TEXT
total 72
drwxr-xr-x   2 root root 4096 Jul  7 10:00 bin
...
Novo conteúdo
root      1234  0.0  0.1  nginx: master

(6) ▶ Exemplo: Combinações Práticas de Pipeline

BASH
# 5 maiores arquivos
ls -lhS | head -6

# Número de Shells em execução
ps aux | grep bash | wc -l

# Partições com uso de disco acima de 80%
df -h | grep -v "tmpfs" | awk '{print $5, $6}' | sort -rn

# Encontrar arquivos de log em /var/log modificados nos últimos 7 dias
find /var/log -name "*.log" -mtime -7 | sort

# Obter o IP externo
curl -s ifconfig.me | tee meu-ip.txt

Saída:

TEXT
-r--r--r-- 1 root root  12K config.pkt
-rw-r--r-- 1 root root 8.9M data.tar.gz
3
203.0.113.42

(7) ▶ Exemplo Abrangente: Cadeia de Pipeline de Análise de Log

BASH
# Simular um log de acesso do Nginx
cat << 'EOF' > /tmp/access.log
192.168.1.100 - - [07/Jul/2026:10:15:30 +0000] "GET /index.html HTTP/1.1" 200 1234
10.0.0.45 - - [07/Jul/2026:10:16:30 +0000] "GET /api/users HTTP/1.1" 200 5678
192.168.1.100 - - [07/Jul/2026:10:17:30 +0000] "POST /api/login HTTP/1.1" 401 234
10.0.0.45 - - [07/Jul/2026:10:18:30 +0000] "GET /api/users HTTP/1.1" 200 5678
192.168.1.200 - - [07/Jul/2026:10:19:30 +0000] "GET /index.html HTTP/1.1" 404 123
10.0.0.45 - - [07/Jul/2026:10:20:30 +0000] "GET /api/users HTTP/1.1" 200 5678
EOF

echo "=== Total de Requisições ==="
wc -l /tmp/access.log

echo ""
echo "=== Contagem de Acesso por IP (Top 5) ==="
cat /tmp/access.log | awk '{print $1}' | sort | uniq -c | sort -rn

echo ""
echo "=== Contagem por Código de Status HTTP ==="
cat /tmp/access.log | awk '{print $9}' | sort | uniq -c | sort -rn

echo ""
echo "=== URLs Mais Acessadas ==="
cat /tmp/access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head -5

echo ""
echo "=== Requisições com Erro 404 ==="
grep " 404 " /tmp/access.log | awk '{print $1, $7}'

❓ Perguntas Frequentes

P: Pipelines são processados em série ou em paralelo? R: \1

P: Pipes e redirecionamento podem ser usados juntos? R: Sim. Por exemplo, command > file 2>&1 (redirecionamento) e command | grep "erro" (pipe) podem ser combinados: command 2>&1 | grep "erro".

P: Um erro no meio do pipeline afeta o resultado final? R: Sim. Se um comando no pipeline falhar, os comandos downstream podem receber dados incompletos. Use set -o pipefail (em scripts) para que a falha de qualquer comando do pipeline cause a falha do pipeline inteiro.

P: Como saio do tail -f? R: Pressione Ctrl + C. O tail -f monitora continuamente o arquivo em busca de novo conteúdo até que você o interrompa manualmente.

P: O processamento de pipelines com arquivos grandes esgota a memória? R: \1


📖 Resumo


📝 Exercícios

  1. Básico (Dificuldade ⭐): Use ls -la | wc -l para contar arquivos, depois use /var/log/syslog ou crie um arquivo de teste para extrair linhas que contêm "erro" e contá-las
  2. Intermediário (Dificuldade ⭐⭐): Use df -h | grep "^/" | sort -k5 -rn para encontrar a partição com o maior uso de disco, e use tee para salvar a saída de ps aux em um arquivo enquanto exibe no terminal
  3. Avançado (Dificuldade ⭐⭐⭐): Combine 3 ou mais comandos de pipeline para uma tarefa de processamento de dados — encontre os 5 processos que mais consomem memória no sistema, ordenados por uso de memória em ordem decrescente, formatados como "PID Comando Memória%"
Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%