Exercícios de find, grep e awk - Resolução de Problemas e Desenvolvimento de Habilidades Práticas
O episódio final. Cobre exercícios de validação de habilidades, correções de problemas comuns e um roteiro de crescimento. O polimento final no seu caminho para se tornar um usuário avançado de Linux.
O Que Você Vai Aprender
- Problemas típicos com find, grep e awk que você encontra em produção
- Exercícios e desafios para validar suas habilidades
- Um roteiro de aprendizado para crescimento continuo
- Um encerramento final no seu caminho para se tornar um usuário avançado de Linux
Problemas Comuns e Correções
Conclusão: Conheça antecipadamente as armadilhas típicas de find, grep e awk e suas correções.
Se você usa esses comandos em produção, vai encontrar esses problemas típicos. Conheça as correções antecipadamente.
Problemas com o Comando find
Uma enxurrada de erros "Permission denied"
Sintomas:
find: '/root': Permission denied find: '/proc/1': Permission denied
Correções:
# Opcao 1: Suprimir saida de erro find / -name "*.txt" 2>/dev/null # Opcao 2: Buscar apenas em locais que voce tem acesso find /home /var /tmp -name "*.txt" # Opcao 3: Executar com sudo (use com cuidado) sudo find / -name "*.txt"
Erros quando nomes de arquivo contêm espaços
Sintoma: "My Document.txt" é interpretado como "My", "Document.txt".
Correções:
# Usar -print0 com xargs -0
find /home -name "*.txt" -print0 | xargs -0 rm
# Usar -exec com +
find /home -name "*.txt" -exec rm {} +Buscas estão muito lentas
Correções:
- Pular diretórios indesejados com
-path - Limitar profundidade com
-maxdepth - Filtrar arquivos com
-type f
find /var -maxdepth 3 -type f -path "*/node_modules" -prune -o -name "*.log" -print
Problemas com o Comando grep
Caracteres multibyte (ex: japoneses) não são buscados corretamente
Correções:
# Verificar e definir locale export LANG=en_US.UTF-8 grep "error" logfile.txt # Evitar classificacao como binario grep -a "error" logfile.txt
Regex não se comporta como esperado
Problemas comuns: +, ?, {} tratados como literais, agrupamento com () não suportado.
Correções:
# Usar -E para regex estendida grep -E "colou?r" file.txt grep -E "(http|https)://" file.txt # Usar o alias egrep egrep "colou?r" file.txt
Erro de correspondência em arquivo binário
Sintoma: Binary file image.jpg matches
Correções:
# Buscar apenas em arquivos de texto grep -I "pattern" * # Restringir tipos de arquivo grep -r --include="*.txt" --include="*.log" "pattern" .
Problemas com o Comando awk
Campos não são divididos como esperado
Sintoma: CSV com vírgulas dentro de campos entre aspas, ex: "Tanaka","28","Tokyo, Shibuya","Engineer, Team Lead".
Correções:
# Usar uma ferramenta dedicada csvtool col 1,2 data.csv # Processar via Python python3 -c " import csv, sys reader = csv.reader(sys.stdin) for row in reader: print(row[0], row[1]) " < data.csv
Problemas de precisão numérica
Sintoma: Cálculos decimais são imprecisos (esperado 10.50, obtido 10.5000000001).
Correções:
# Usar printf com precisao
awk '{sum+=$1} END {printf "%.2f\n", sum}' numbers.txt
# Processar via bc
awk '{print $1}' numbers.txt | paste -sd+ | bcTécnicas de Depuração
Verifique incrementalmente
Execute comandos complexos parte por parte.
# Comando final find /var/log -name "*.log" | xargs grep -l "ERROR" | xargs wc -l # Passos de depuracao # 1. Executar apenas a parte do find find /var/log -name "*.log" # 2. Executar ate o grep find /var/log -name "*.log" | xargs grep -l "ERROR" # 3. Executar o comando completo find /var/log -name "*.log" | xargs grep -l "ERROR" | xargs wc -l
Salvar resultados intermediários
Para pipelines de longa duração, salve a saída intermediária.
find /var -name "*.log" > all_logs.txt grep -l "ERROR" $(cat all_logs.txt) > error_logs.txt wc -l $(cat error_logs.txt) > final_result.txt
Habilidades Adicionais
Agora que você domina find, grep e awk, aqui estão as habilidades para aprender em seguida.
Comandos de Próximo Nível
sed (editor de fluxo): Substituição, exclusão e inserção rápida de texto.
sed 's/error/ERROR/g' logfile.txt
Prioridade: Mais alta.
xargs (conversão de argumentos): Converter saída de pipe em argumentos de linha de comando.
find . -name "*.txt" | xargs -P 4 wc -l
Prioridade: Mais alta.
sort/uniq (ordenar e deduplicar): Reordenar dados e deduplicar.
cat access.log | awk '{print $1}' | sort | uniq -c | sort -rnPrioridade: Alta.
join/paste (junção de arquivos): Mesclar dados de múltiplos arquivos.
join -t, file1.csv file2.csv
Prioridade: Média.
Exercícios e Desafios
Conclusão: Exercícios práticos e graduais permitem verificar e consolidar suas habilidades.
Consolide habilidades com prática. Enfrente esses desafios para verificar seu nível.
Desafios para Iniciantes
Desafio 1: Básicos de busca de arquivos
Em /var/log e subpastas, encontre arquivos com extensão .log que tenham 1MB ou mais.
Desafio 1 - Mostrar dica
Combine -name e -size com find.
Desafio 1 - Mostrar solução
find /var/log -name "*.log" -size +1M
Desafio 2: Básicos de busca de texto
Busque em system.log por linhas contendo "ERROR" e mostre com números de linha.
Desafio 2 - Mostrar solução
grep -n "ERROR" system.log
Desafio 3: Básicos de agregação de dados
Calcule a soma da coluna 3 (vendas) em sales.csv.
Desafio 3 - Mostrar solução
awk -F',' '{sum += $3} END {print "Soma:", sum}' sales.csvDesafios Intermediários
Desafio 4: Pipeline de análise de logs
Conte os endereços IP únicos de hoje no log de acesso.
Desafio 4 - Mostrar dica
Filtre pela data de hoje com grep, extraia o IP com awk, deduplicar com sort/uniq.
Desafio 4 - Mostrar solução
grep "$(date '+%d/%b/%Y')" access.log | awk '{print $1}' | sort -u | wc -lDesafio 5: Busca em arquivos grandes
A partir do diretório home, encontre os 5 maiores arquivos com 100MB ou mais e exiba por tamanho.
Desafio 5 - Mostrar solução
find /home -type f -size +100M -exec ls -lh {} \; | sort -rh -k5 | head -5Desafio 6: Relatório de estatísticas de erros
A partir de múltiplos arquivos de log, agregue categorias de erros e mostre em ordem decrescente.
Desafio 6 - Mostrar solução
find /var/log -name "*.log" | xargs grep -h "ERROR" | awk '{print $4}' | sort | uniq -c | sort -rnDesafios Avançados
Desafio 7: Script de monitoramento de website
A partir dos logs de acesso do Apache, encontre IPs com 10 ou mais erros 404 na última hora e produza mensagens de alerta.
Desafio 7 - Mostrar dica
Filtre por hora, extraia 404, agrupe por IP, filtre por limite.
Desafio 7 - Mostrar solução
hour_ago=$(date -d '1 hour ago' '+%d/%b/%Y:%H')
current_hour=$(date '+%d/%b/%Y:%H')
grep -E "($hour_ago|$current_hour)" /var/log/apache2/access.log | \
grep " 404 " | \
awk '{print $1}' | \
sort | uniq -c | \
awk '$1 >= 10 {printf "ALERTA: IP %s tem %d erros 404 na ultima hora\n", $2, $1}'Desafio 8: Verificação de qualidade de dados
Construa um script que verifique a qualidade dos dados CSV e reporte total de linhas/colunas, linhas vazias, valores únicos por coluna e min/max/média das colunas numéricas.
Desafio 8 - Mostrar solução
awk -F',' '
NR == 1 {
num_columns = NF
for (i = 1; i <= NF; i++) headers[i] = $i
next
}
NF == 0 { empty_lines++; next }
{
total_rows++
for (i = 1; i <= num_columns && i <= NF; i++) {
field_values[i][$i] = 1
if ($i ~ /^[0-9]+\.?[0-9]*$/) {
numeric_count[i]++
numeric_sum[i] += $i
if (numeric_min[i] == "" || $i < numeric_min[i]) numeric_min[i] = $i
if (numeric_max[i] == "" || $i > numeric_max[i]) numeric_max[i] = $i
}
}
}
END {
printf "Linhas: %d\n", total_rows
printf "Colunas: %d\n", num_columns
printf "Linhas vazias: %d\n", empty_lines + 0
for (i = 1; i <= num_columns; i++) {
printf "Col%d (%s): unicos=%d", i, headers[i], length(field_values[i])
if (numeric_count[i] > 0) {
avg = numeric_sum[i] / numeric_count[i]
printf ", min=%.2f, max=%.2f, media=%.2f", numeric_min[i], numeric_max[i], avg
}
print ""
}
}' data.csvDesafio 9: Script de backup automatizado
Construa um script de backup para arquivos importantes. Apenas arquivos alterados desde o último backup; apenas arquivos menores que 100MB; registre todas as operações de backup; exclua automaticamente backups antigos (mais de 7 dias).
Desafio 9 - Mostrar solução
#!/bin/bash
BACKUP_DIR="/backup/$(date +%Y%m%d_%H%M%S)"
LAST_BACKUP_MARKER="/var/log/last_backup.timestamp"
LOG_FILE="/var/log/backup.log"
echo "=== Backup iniciado em $(date) ===" >> "$LOG_FILE"
mkdir -p "$BACKUP_DIR"
find /home/important -type f -size -100M -newer "$LAST_BACKUP_MARKER" 2>/dev/null | \
while read file; do
rel_path="${file#/home/important/}"
backup_path="$BACKUP_DIR/$rel_path"
backup_dir=$(dirname "$backup_path")
mkdir -p "$backup_dir"
if cp "$file" "$backup_path" 2>/dev/null; then
echo "Backup realizado: $file" >> "$LOG_FILE"
fi
done
# Excluir backups antigos
find /backup -type d -mtime +7 -exec rm -rf {} + 2>/dev/null
# Atualizar timestamp
date > "$LAST_BACKUP_MARKER"Desafio Mestre
Desafio 10: Painel de monitoramento abrangente do sistema
Construa um script de monitoramento do sistema com:
- Monitoramento de logs em tempo real
- Alerta automático sobre erros
- Visualização de uso de recursos
- Geração de relatório diário
- Confirmação via web (relatório HTML)
Desafio 10 - Dica de abordagem
Use tail -f para monitoramento em tempo real, awk para estatísticas, find para gerenciamento de arquivos antigos, templates HTML para relatórios.
Completar este desafio significa que você pode se chamar com confiança de usuário avançado de Linux.