Tecnicas Avancadas de grep e awk - Serie Mestre find/grep/awk

Tecnicas Avancadas de grep e awk - Serie Mestre find/grep/awk

O guia avancado cobre otimizacao de grep com variaveis de ambiente, ferramentas de busca de alta velocidade de nova geracao e arrays associativos, funcoes definidas pelo usuario e processamento de fluxo do awk. Domine tecnicas de processamento de dados em nivel profissional.

O Que Voce Vai Aprender

  • Opcoes avancadas do grep e otimizacao com variaveis de ambiente
  • Ferramentas de busca de alta velocidade de nova geracao como ripgrep
  • Arrays associativos, funcoes definidas pelo usuario e processamento de fluxo do awk
  • Tecnicas de processamento de texto e manipulacao de dados em nivel profissional

Comando grep: O Mago da Busca de Texto

Conclusao: grep extrai linhas que correspondem a um padrao; regex e ferramentas rapidas o potencializam.

grep significa "Global Regular Expression Print". Ele extrai linhas que correspondem a um padrao de arquivos ou entrada. Combinado com expressoes regulares, torna-se uma ferramenta de busca extremamente poderosa.

Sintaxe Basica

grep [opcoes] padrao nomedoarquivo

Uso Basico

Busca de string:

# Exibir linhas contendo "Linux"
grep "Linux" document.txt

# Busca sem diferenciar maiusculas/minusculas
grep -i "linux" document.txt

# Exibir linhas que NAO contem "error" (busca inversa)
grep -v "error" log.txt

Numeros de linha e contexto:

# Mostrar numeros de linha
grep -n "function" script.js

# Mostrar 3 linhas antes e depois
grep -C 3 "ERROR" app.log

# Mostrar 1 linha antes e 2 linhas depois
grep -A 2 -B 1 "WARNING" app.log

Busca em arquivos e contagem:

# Mostrar apenas nomes de arquivos contendo "TODO"
grep -l "TODO" *.js

# Contar linhas contendo "error"
grep -c "error" log.txt

# Busca recursiva (nota: /etc/ pode conter informacoes sensiveis)
grep -r "password" /etc/

Combinando com Expressoes Regulares

O verdadeiro poder do grep vem da combinacao com expressoes regulares.

# Linhas comecando com "Linux"
grep "^Linux" document.txt

# Linhas terminando com "finished"
grep "finished$" log.txt

# Linhas vazias
grep "^$" file.txt

# Linhas contendo um ou mais digitos
grep -E "[0-9]+" numbers.txt

# Corresponder "color" ou "colour"
grep -E "colou?r" text.txt

# Corresponder qualquer um de multiplos padroes (OR)
grep -E "error|warning|fatal" log.txt

Padroes praticos:

# Padrao de endereco IP
grep -E "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" access.log

# Padrao de endereco de e-mail
grep -E "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}" contacts.txt

# Padrao de data (AAAA-MM-DD)
grep -E "20[0-9]{2}-[0-1][0-9]-[0-3][0-9]" log.txt

Combinando grep com Pipes

Voce pode construir pipelines de processamento de dados poderosos encadeando com outros comandos.

# Mostrar apenas processos nginx
ps aux | grep "nginx"

# Excluir o proprio grep ao filtrar
ps aux | grep -v "grep" | grep "python"

# Monitoramento de erros em tempo real
tail -f /var/log/app.log | grep --line-buffered "ERROR"

# Contar erros 404
cat access.log | grep "404" | wc -l

# Mostrar processos escutando na porta 80
netstat -an | grep ":80 "

Tecnicas de Aceleracao

Variaveis de ambiente e otimizacao de locale melhoram significativamente o desempenho em arquivos grandes.

# Eliminar overhead de processamento UTF-8 (ate 10x mais rapido)
LC_ALL=C grep "ERROR" huge_log.txt

# Pular arquivos binarios
LC_ALL=C grep --binary-files=without-match "pattern" /var/log/*

# Desativar cores para velocidade adicional
GREP_OPTIONS="--color=never" LC_ALL=C grep -F "ERROR" *.log

# Busca de string fixa (pular motor de regex)
grep -F "literal_string" file.txt

grep de Nova Geracao: ripgrep e ag

Alternativas mais rapidas e ricas em recursos ao grep tradicional.

ripgrep (rg) - grep rapido baseado em Rust:

# Buscar apenas arquivos JavaScript (rapido)
rg --type js "function" /var/www/

# Saida JSON para processamento estruturado
rg --json "ERROR" /var/log/ | jq '.data.lines.text'

# Mostrar estatisticas e contagens
rg --stats --count "TODO" ./src/

ag (The Silver Searcher):

# Processamento paralelo multi-core
ag --parallel "pattern" /large/directory/

# Mostrar 5 linhas de contexto, agrupadas
ag --context=5 --group "ERROR" /var/log/

Comparacao de desempenho (busca em arquivo de 1GB):

Ferramenta Tempo Memoria Notas
grep 15.2s 2MB Padrao, estavel
LC_ALL=C grep 8.1s 2MB Otimizado
ripgrep (rg) 2.3s 8MB Mais rapido, rico em recursos
ag 4.1s 12MB Rapido, amigavel ao dev

Processamento de Arquivos Grandes

# Monitoramento de log em tempo real com busca
tail -f /var/log/huge.log | grep --line-buffered "ERROR"

# Buscar em arquivos compactados diretamente
zgrep "ERROR" /var/log/app.log.gz

# Arquivos bzip2 tambem
bzgrep "pattern" archive.log.bz2

# Dividir arquivos grandes para processamento paralelo
split -l 1000000 huge.log chunk_ && grep "ERROR" chunk_* | sort

Geracao de Relatorios

# Gerar relatorio CSV de erros
grep -n "ERROR" *.log | awk -F: '{print $1","$2","$3}' > error_report.csv

# Relatorio abrangente de analise de erros
{
  echo "=== ERROR Analysis Report $(date) ==="
  echo "Total errors: $(grep -c ERROR app.log)"
  echo "Top 5 errors:"
  grep -o 'ERROR.*' app.log | sort | uniq -c | sort -nr | head -5
}

Comando awk: O Magico do Processamento de Dados

Conclusao: awk processa dados por coluna com arrays, funcoes e tratamento de fluxo.

awk tem o nome de "Alfred Aho, Peter Weinberger, Brian Kernighan" (as iniciais de seus criadores). E uma linguagem poderosa de processamento de texto que se destaca com arquivos CSV e arquivos de log.

Como o awk Pensa

awk processa a entrada como registros (tipicamente linhas) e campos (tipicamente colunas).

Name,Age,Job
Tanaka,25,Engineer
Sato,30,Designer
Yamada,28,Manager
  • $1: Primeiro campo (Name)
  • $2: Segundo campo (Age)
  • $3: Terceiro campo (Job)
  • $0: Registro inteiro
  • NF: Numero de campos
  • NR: Numero do registro

Sintaxe Basica

awk 'padrao { acao }' arquivo

Execute uma acao nas linhas que correspondem a um padrao.

Operacoes Basicas do awk

Extraindo colunas:

# Imprimir coluna 1
awk '{print $1}' employees.csv

# Imprimir colunas 2 e 3
awk '{print $2, $3}' employees.csv

# Imprimir com numero de linha
awk '{print NR ": " $0}' file.txt

Especificando delimitadores:

# Separado por virgula, coluna 1
awk -F ',' '{print $1}' data.csv

# Separado por dois-pontos /etc/passwd, usuario e UID
awk -F ':' '{print $1, $3}' /etc/passwd

# Separado por tab, coluna 2
awk 'BEGIN {FS="\t"} {print $2}' tab_separated.txt

Processamento condicional:

# Mostrar pessoas com mais de 25 anos
awk '$2 > 25 {print $1, $2}' employees.csv

# Mostrar engenheiros
awk '$3 == "Engineer" {print $1}' employees.csv

# Mostrar linhas com mais de 3 campos
awk 'NF > 3 {print NR, $0}' data.txt

Calculos e Agregacao

Calculos basicos:

# Soma da coluna 3
awk '{sum += $3} END {print "Sum:", sum}' sales.csv

# Media da coluna 2
awk '{sum += $2; count++} END {print "Avg:", sum/count}' ages.txt

# Maximo da coluna 2
awk 'BEGIN {max=0} {if($2>max) max=$2} END {print "Max:", max}' numbers.txt

Agregacao por grupo:

# Soma de salarios por departamento
awk '{dept[$3] += $2} END {for (d in dept) print d, dept[d]}' salary.csv

# Contagem de acessos por IP
awk '{count[$1]++} END {for (c in count) print c, count[c]}' access.log

Padroes BEGIN e END

  • BEGIN: Executa antes de processar o arquivo
  • END: Executa depois de processar o arquivo
# Imprimir cabecalho antes de processar dados
awk 'BEGIN {print "Start", "Name", "Age"} {print NR, $1, $2}' data.txt

# Imprimir total de registros apos processamento
awk '{count++} END {print "Total records:", count}' data.txt

# Agregacao de vendas estilo relatorio
awk 'BEGIN {print "=== Sales Report ==="} {total+=$3} END {print "Total:", total}' sales.txt

Uso Avancado

# Processar multiplos arquivos com rotulos de nome de arquivo
awk 'FNR==1{print "=== " FILENAME " ==="} {print NR, $0}' file1.txt file2.txt

# Adicionar aprovado/reprovado baseado em condicao
awk '{if($2>=60) grade="Pass"; else grade="Fail"; print $1, $2, grade}' scores.txt

Dominando Arrays Associativos

O verdadeiro poder do awk reside nos arrays associativos (tabelas hash). Eles se destacam no processamento de dados multidimensionais.

Agregacao multidimensional (vendas por regiao x mes):

awk -F, '
NR>1 {
    sales[$2][$3] += $4;
    total_by_region[$2] += $4;
    total_by_month[$3] += $4;
    grand_total += $4;
}
END {
    printf "%-12s", "Region/Month";
    for (month in total_by_month) printf "%10s", month;
    printf "%12s\n", "Region Total";

    for (region in total_by_region) {
        printf "%-12s", region;
        for (month in total_by_month) {
            printf "%10d", (month in sales[region]) ? sales[region][month] : 0;
        }
        printf "%12d\n", total_by_region[region];
    }
}' sales_data.csv

Funcoes Definidas pelo Usuario

Reutilize logica complexa com funcoes para codigo mais manutencivel.

Biblioteca estatistica:

awk '
function average(arr, count,    sum, i) {
    sum = 0;
    for (i = 1; i <= count; i++) sum += arr[i];
    return sum / count;
}

function stddev(arr, count,    avg, sum_sq, i) {
    avg = average(arr, count);
    sum_sq = 0;
    for (i = 1; i <= count; i++) {
        sum_sq += (arr[i] - avg) ^ 2;
    }
    return sqrt(sum_sq / count);
}

{
    if (NF >= 2 && $2 ~ /^[0-9]+\.?[0-9]*$/) {
        values[++count] = $2;
        sum += $2;
    }
}

END {
    if (count > 0) {
        printf "n=%d\n", count;
        printf "Avg:    %.2f\n", average(values, count);
        printf "StdDev: %.2f\n", stddev(values, count);
    }
}' numerical_data.txt

Processamento de Fluxo e getline

Processamento de dados em tempo real e integracao com comandos externos se destacam aqui.

Monitoramento de log em tempo real:

tail -f /var/log/apache2/access.log | awk '
BEGIN {
    window_size = 300;
    alert_threshold = 100;
}
{
    "date +%s" | getline current_time;
    close("date +%s");

    access_times[current_time]++;

    for (time in access_times) {
        if (current_time - time > window_size) {
            delete access_times[time];
        }
    }

    total_access = 0;
    for (time in access_times) total_access += access_times[time];

    if (total_access > alert_threshold) {
        printf "[ALERT] High traffic: %d requests in last 5 minutes\n", total_access;
    }
}'

Otimizacao de Desempenho

Tecnicas de aceleracao do awk

  • Evite concatenacao de strings desnecessaria (use arrays)
  • Faca delete periodicamente em estruturas de dados grandes
  • Processe apenas os campos que voce precisa
  • Inicialize constantes no BEGIN

Processamento de arquivos grandes com eficiencia de memoria:

awk '
BEGIN {
    processed = 0;
    batch_size = 10000;
}
{
    process_record($0);
    processed++;

    if (processed % batch_size == 0) {
        cleanup_memory();
        printf "Processed: %d records\n", processed > "/dev/stderr";
    }
}

function process_record(record,    fields) {
    split(record, fields, ",");
    if (fields[2] > threshold) {
        summary[fields[1]] += fields[3];
    }
}

function cleanup_memory(    key) {
    for (key in old_cache) delete old_cache[key];
}

END {
    for (key in summary) printf "%s: %d\n", key, summary[key];
}' huge_data_file.csv

Formatacao Avancada de Saida

Geracao de grafico ASCII art:

awk -F, '
NR > 1 { sales[$1] += $3; }
END {
    max_sales = 0;
    for (person in sales) {
        if (sales[person] > max_sales) max_sales = sales[person];
    }
    chart_width = 50;
    scale = max_sales / chart_width;

    print "Sales Chart";
    print "===========";

    for (person in sales) {
        bar_length = int(sales[person] / scale);
        printf "%-10s |", person;
        for (j = 1; j <= bar_length; j++) printf "█";
        printf " %d\n", sales[person];
    }
}' sales_report.csv

Proximos Passos

Leve as tecnicas de grep e awk aprendidas aqui adiante com o guia pratico.