Combinando find, grep e awk - Tecnicas Praticas para o Trabalho Real
O guia pratico explica padroes praticos de processamento de dados combinando find, grep e awk, casos de uso do mundo real e otimizacao de desempenho. Domine habilidades imediatamente utilizaveis para engenheiros e analistas de dados.
O Que Voce Vai Aprender
- Padroes praticos que conectam find, grep e awk via pipe
- Casos de uso e fluxos de trabalho do mundo real organizados por funcao profissional
- Dicas de otimizacao de desempenho para lidar com grandes conjuntos de dados
- Habilidades de processamento de dados imediatamente utilizaveis no campo
Tecnicas de Combinacao
Conclusao: Conectar find, grep e awk via pipe transforma tarefas dificeis em solucoes poderosas.
Um verdadeiro mestre em Linux usa find, grep e awk juntos. Tarefas que sao dificeis com um unico comando se tornam solucoes poderosas quando combinadas.
Padroes Basicos de Pipe
find + grep:
# Encontrar arquivos de log contendo ERROR
find /var/log -name "*.log" -exec grep -l "ERROR" {} \;
# Buscar "password" em arquivos txt com numeros de linha
find /home -name "*.txt" | xargs grep -n "password"grep + awk:
# Extrair data, hora e ultimo campo de linhas de erro
grep "ERROR" /var/log/app.log | awk '{print $1, $2, $NF}'
# Somar uso de CPU dos processos nginx
ps aux | grep "nginx" | awk '{sum+=$4} END {print "Total CPU:", sum "%"}'find + awk:
# Calcular tamanho total e contagem de arquivos de log
find /var -name "*.log" -printf "%s %p\n" | awk '{size+=$1; count++} END {printf "Total: %.2f MB Arquivos: %d\n", size/1024/1024, count}'Processamento Combinado no Mundo Real
Cenario 1: Analise de acesso ao servidor web
Extrair os 10 principais enderecos IP com mais erros da ultima semana.
find /var/log/apache2 -name "access.log*" -mtime -7 | \
xargs grep " 5[0-9][0-9] " | \
awk '{print $1}' | \
sort | uniq -c | \
sort -rn | \
head -10 | \
awk '{printf "%-15s %d vezes\n", $2, $1}'Explicacao passo a passo:
find: Encontrar logs de acesso dos ultimos 7 diasgrep: Extrair linhas com erros 5xx (erros do servidor)awk: Extrair enderecos IP (coluna 1)sort | uniq -c: Contar por endereco IPsort -rn: Ordenar por contagem decrescentehead -10: Top 10awk: Formatar saida
Cenario 2: Exclusao em massa de arquivos temporarios antigos
Excluir com seguranca arquivos temporarios com mais de 30 dias do sistema.
# 1. Primeiro verificar os arquivos alvo
find /tmp /var/tmp /home -name "*.tmp" -o -name "temp*" -o -name "*.temp" | \
xargs ls -la
# 2. Apos confirmar, executar a exclusao
find /tmp /var/tmp /home -name "*.tmp" -mtime +30 -size +0 | \
xargs -I {} bash -c 'echo "Excluir: {}"; rm "{}"'Sempre liste e verifique os arquivos alvo antes da exclusao. Direcione apenas arquivos com mais de 30 dias e tamanho maior que zero.
Cenario 3: Analise de log de conexao de banco de dados
Analisar contagens de conexao MySQL por hora no log.
find /var/log/mysql -name "*.log" -mtime -1 | \
xargs grep -h "Connect" | \
awk '{
match($0, /[0-9]{4}-[0-9]{2}-[0-9]{2}T([0-9]{2})/, time_parts);
hour = time_parts[1];
connections[hour]++;
}
END {
print "Conexoes MySQL por hora (ultimas 24h)";
for (h = 0; h < 24; h++) {
printf "%02d:00-%02d:59 | ", h, h;
count = (h in connections) ? connections[h] : 0;
printf "%5d ", count;
for (i = 0; i < count/10; i++) printf "▓";
printf "\n";
}
}'One-Liners Uteis
One-liners convenientes comumente usados na pratica. Prontos para uso, com alto valor pratico.
Gerenciamento de disco e arquivos:
# Top 20 maiores arquivos
find . -type f -exec du -h {} + | sort -rh | head -20
# Calcular tamanho total de arquivos de log antigos
find /var -name "*.log" -mtime +7 -exec ls -lh {} \; | awk '{size+=$5} END {print "Tamanho recuperavel:", size/1024/1024 "MB"}'Analise de rede e acesso:
# Top 10 IPs por contagem de acesso hoje
grep "$(date '+%d/%b/%Y')" /var/log/apache2/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -10
# IPs com mais falhas de login SSH
find /var/log -name "*.log" | xargs grep -h "Failed password" | awk '{print $11}' | sort | uniq -c | sort -rnMonitoramento do sistema:
# Uso de memoria por processo
find /proc -maxdepth 2 -name "status" 2>/dev/null | xargs grep -l "VmRSS" | xargs -I {} bash -c 'echo -n "$(basename $(dirname {})): "; grep VmRSS {}'
# Fontes de erros/avisos do sistema hoje
find /var/log -name "syslog*" | xargs grep "$(date '+%b %d')" | grep -i "error\|warn\|fail" | awk '{print $5}' | sort | uniq -c | sort -rnPadroes de Design de Pipeline
Padroes de tratamento e recuperacao de erros:
Em producao, falhas sao esperadas. Designs que tratam erros e continuam o processamento sao importantes.
#!/bin/bash
set -euo pipefail
handle_error() {
echo "ERROR: falha no pipeline na linha $1" >&2
exit 1
}
trap 'handle_error $LINENO' ERR
process_logs_safely() {
local input_pattern="$1"
local output_file="$2"
local temp_dir="/tmp/pipeline_$$"
mkdir -p "$temp_dir"
find /var/log -name "$input_pattern" -type f 2>/dev/null > "$temp_dir/file_list" || {
echo "AVISO: alguns arquivos nao acessiveis" >&2
}
if [[ ! -s "$temp_dir/file_list" ]]; then
echo "ERRO: sem arquivos alvo" >&2
rm -rf "$temp_dir"
return 1
fi
while IFS= read -r logfile; do
if [[ -r "$logfile" ]]; then
grep -h "ERROR\|WARN" "$logfile" 2>/dev/null >> "$temp_dir/errors.log" || true
fi
done < "$temp_dir/file_list"
if [[ -s "$temp_dir/errors.log" ]]; then
awk '
{
if ($0 ~ /ERROR/) error_count++;
if ($0 ~ /WARN/) warn_count++;
}
END {
printf "ERROR: %d\n", error_count;
printf "WARN: %d\n", warn_count;
}' "$temp_dir/errors.log" > "$output_file"
fi
rm -rf "$temp_dir"
}Pipeline de processamento paralelo:
Acelere processamento intensivo de CPU com paralelismo.
parallel_log_analysis() {
local log_pattern="$1"
local output_dir="$2"
local cpu_cores=$(nproc)
local max_parallel=$((cpu_cores - 1))
find /var/log -name "$log_pattern" -type f | \
xargs -n 1 -P "$max_parallel" -I {} bash -c '
logfile="$1"
output_dir="$2"
result_file="$output_dir/result_$$.tmp"
grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" "$logfile" | \
awk "
{
ip = \$1;
if (match(ip, /^192\.168\./)) region = \"local\";
else if (match(ip, /^10\./)) region = \"internal\";
else region = \"external\";
total_by_region[region]++;
}
END {
for (region in total_by_region) {
printf \"region:%s total:%d\n\", region, total_by_region[region];
}
}" > "$result_file"
' -- {} "$output_dir"
}Casos de Uso no Mundo Real
Conclusao: Exemplos por funcao mostram como os tres comandos ajudam no trabalho real.
Pratica sobre teoria. Exemplos por funcao profissional.
Engenheiro Web
Resposta a incidente repentino em producao
Relatorio de "Site esta lento". Necessidade de identificar a causa rapidamente.
# 1. Verificar logs de erro
find /var/log/apache2 /var/log/nginx -name "*.log" | xargs grep -E "$(date '+%d/%b/%Y')" | grep -E "5[0-9][0-9]|error|timeout" | tail -50
# 2. Identificar consultas lentas
find /var/log/mysql -name "*slow.log" | xargs grep -A 5 "Query_time" | awk '/Query_time: [5-9]/ {getline; print}'
# 3. Detectar padroes de acesso anormais
grep "$(date '+%d/%b/%Y')" /var/log/apache2/access.log | awk '{print $1}' | sort | uniq -c | awk '$1 > 1000 {print "Anormal:", $2, "contagem:", $1}'Tarefas que levam 30-60 minutos manualmente sao concluidas em 5 minutos.
Geracao de relatorio mensal
Resumir as estatisticas de acesso e taxas de erro do ultimo mes.
#!/bin/bash
LAST_MONTH=$(date -d "last month" '+%b/%Y')
echo "=== Estatisticas de Acesso $LAST_MONTH ==="
# Total de acessos
TOTAL_ACCESS=$(find /var/log/apache2 -name "access.log*" | xargs grep "$LAST_MONTH" | wc -l)
echo "Total de acessos: $TOTAL_ACCESS"
# Visitantes unicos
UNIQUE_VISITORS=$(find /var/log/apache2 -name "access.log*" | xargs grep "$LAST_MONTH" | awk '{print $1}' | sort -u | wc -l)
echo "Visitantes unicos: $UNIQUE_VISITORS"
# Taxa de erro
ERROR_COUNT=$(find /var/log/apache2 -name "access.log*" | xargs grep "$LAST_MONTH" | grep -E " [45][0-9][0-9] " | wc -l)
ERROR_RATE=$(echo "scale=2; $ERROR_COUNT * 100 / $TOTAL_ACCESS" | bc)
echo "Taxa de erro: $ERROR_RATE%"Engenheiro de Infraestrutura
Monitoramento e manutencao de servidores
Verificacao periodica de saude de multiplos servidores.
#!/bin/bash
echo "=== Relatorio de Saude do Servidor ==="
date
# Aviso de uso de disco
echo "=== Uso de Disco (aviso acima de 80%) ==="
df -h | awk 'NR>1 {gsub(/%/, "", $5); if($5 > 80) printf "AVISO: %s: %s usado (%s%%)\n", $6, $3, $5}'
# Uso de memoria
echo "=== Uso de Memoria ==="
free -m | awk 'NR==2{printf "Memoria: %.1f%% (%dMB / %dMB)\n", $3*100/$2, $3, $2}'
# Processos com maior uso de CPU
echo "=== Top 5 CPU ==="
ps aux --no-headers | sort -rn -k3 | head -5 | awk '{printf "%-10s %5.1f%% %s\n", $1, $3, $11}'
# Verificacao de pico de erros recentes
echo "=== Erros na ultima hora ==="
find /var/log -name "*.log" -mmin -60 | xargs grep -h -E "$(date '+%b %d %H')|$(date -d '1 hour ago' '+%b %d %H')" | grep -ci errorAnalista de Dados
Pre-processamento de grandes dados
Arquivo CSV de varios GB nao pode ser aberto no Excel. Precisa de pre-processamento.
#!/bin/bash
CSV_FILE="sales_data_2024.csv"
OUTPUT_DIR="processed_data"
mkdir -p $OUTPUT_DIR
# Tamanho do arquivo e contagem de linhas
echo "Tamanho do arquivo: $(du -h "$CSV_FILE" | cut -f1)"
echo "Total de linhas: $(wc -l < "$CSV_FILE")"
# Verificacao de qualidade dos dados
echo "Linhas vazias: $(grep -c '^$' "$CSV_FILE")"
echo "Linhas invalidas: $(awk -F',' 'NF != 5 {count++} END {print count+0}' "$CSV_FILE")"
# Dividir em arquivos mensais
awk -F',' 'NR==1 {header=$0; next}
{
month=substr($1,1,7);
if(!seen[month]) {
print header > "'$OUTPUT_DIR'/sales_" month ".csv";
seen[month]=1;
}
print $0 > "'$OUTPUT_DIR'/sales_" month ".csv"
}' "$CSV_FILE"
# Resumo mensal
find $OUTPUT_DIR -name "sales_*.csv" | sort | while read file; do
month=$(basename "$file" .csv | cut -d'_' -f2)
total_sales=$(awk -F',' 'NR>1 {sum+=$4} END {print sum}' "$file")
record_count=$(expr $(wc -l < "$file") - 1)
printf "%s: %d registros, vendas totais: %d\n" "$month" "$record_count" "$total_sales"
doneEstudos de Caso da Industria
Desenvolvimento de jogos: analise de logs em larga escala
Detectar trapaça a partir de 100GB/dia de logs de acoes dos jogadores.
analyze_game_logs() {
local log_date="$1"
local output_dir="/analysis/$(date +%Y%m%d)"
mkdir -p "$output_dir"
find /game/logs -name "*${log_date}*.log" -type f | \
xargs grep -h "PLAYER_ACTION" | \
awk -F'|' '
{
player_id = $3;
action = $4;
value = $5;
# Detectar acoes massivas rapidas
if (action == "LEVEL_UP") {
player_levelups[player_id]++;
if (player_levelups[player_id] > 10) {
print "SUSPICIOUS_LEVELUP", player_id > "/tmp/cheat_suspects.log";
}
}
# Pico anormal de moeda
if (action == "GOLD_CHANGE" && value > 1000000) {
print "SUSPICIOUS_GOLD", player_id, value > "/tmp/gold_anomaly.log";
}
player_actions[player_id]++;
total_actions++;
}
END {
avg_actions = total_actions / length(player_actions);
for (player in player_actions) {
if (player_actions[player] > avg_actions * 5) {
printf "HIGH_ACTIVITY: %s (%d acoes)\n", player, player_actions[player];
}
}
}'
}E-commerce: analise de comportamento do cliente
Analisar padroes de compra a partir dos logs de acesso do site de e-commerce.
analyze_customer_journey() {
local analysis_period="$1"
local output_dir="/analytics/customer_journey"
mkdir -p "$output_dir"
find /var/log/nginx -name "access.log*" | \
xargs grep "$analysis_period" | \
awk '
BEGIN { session_timeout = 1800; }
{
ip = $1;
url = $7;
if (url ~ /\/checkout|\/purchase/) {
purchase_sessions[ip]++;
}
if (url ~ /\/products\/([0-9]+)/) {
match(url, /\/products\/([0-9]+)/, product_match);
product_views[product_match[1]]++;
}
}
END {
print "=== Analise da Jornada do Cliente ===";
for (product in product_views) {
printf "Produto %s: %d visualizacoes\n", product, product_views[product];
}
}'
}Otimizacao de Desempenho
Conclusao: Limite o escopo, use strings fixas e elimine desperdicio para rodar rapido em grandes dados.
Tecnicas Basicas de Aceleracao
# 1. Limitar escopo de busca find /var/log -name "*.log" # Bom # find / -name "*.log" # Ruim (lento) # 2. Otimizacao de locale LC_ALL=C grep "ERROR" huge.log # 3. Strings fixas com -F grep -F "literal_string" file.txt # 4. Pular diretorios indesejados find /var -path "*/node_modules" -prune -o -name "*.log" -print
Tecnicas Avancadas de Otimizacao
# Processamento paralelo find /var/log -name "*.log" | xargs -P 4 grep "ERROR" # Buscar em arquivos compactados diretamente zgrep "ERROR" /var/log/app.log.gz # Leitura rapida de arquivo via memmap (GNU grep) grep --mmap "ERROR" huge_file.log
Medicao de Desempenho
# Medir tempo de execucao
time grep "ERROR" /var/log/huge.log
# Uso detalhado de recursos
/usr/bin/time -v grep "ERROR" /var/log/huge.log
# Efeito do processamento paralelo
for cores in 1 2 4 8; do
echo "cores: $cores"
time find /var/log -name "*.log" | xargs -P $cores grep -c "ERROR"
done