Combinando find, grep e awk - Tecnicas Praticas para o Trabalho Real

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:

  1. find: Encontrar logs de acesso dos ultimos 7 dias
  2. grep: Extrair linhas com erros 5xx (erros do servidor)
  3. awk: Extrair enderecos IP (coluna 1)
  4. sort | uniq -c: Contar por endereco IP
  5. sort -rn: Ordenar por contagem decrescente
  6. head -10: Top 10
  7. awk: 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 -rn

Monitoramento 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 -rn

Padroes 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 error

Analista 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"
done

Estudos 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

Proximos Passos

Leve as tecnicas de combinacao do guia pratico adiante com os exercicios e resolucao de problemas do guia profissional.