Linux: Busca em Texto — grep e Expressões Regulares

Encontrar aquela única linha entre milhares de arquivos — essa é a especialidade do grep. Provavelmente é o comando mais usado no Linux.

📋 Pré-requisitos: Você já deve conhecer

1. O Que Você Vai Aprender


2. A História de Encontrar Código em Cem Arquivos

(1) O Problema: Mudar o Nome de uma API, Mas Não Saber Quais Arquivos a Usam

Alex precisava mudar todas as chamadas de requests.get para httpx.get em arquivos Python. O projeto tinha mais de 100 arquivos — abri-los um por um era impossível.

(2) grep Busca Recursiva

BASH
grep -rn "requests\.get" --include="*.py" src/

Saída:

TEXT
src/api/client.py:15: response = requests.get(url, headers=headers)
src/api/users.py:42: data = requests.get(f"{API_URL}/users")
src/api/orders.py:78: result = requests.get(ORDER_URL)

3 arquivos com chamadas — encontrados em menos de um segundo.

(3) O Benefício: De Agulha no Palheiro à Precisão Absoluta

Alex criou o hábito: antes de mudar código, usar grep -rn para encontrar todas as localizações relacionadas, confirmar e só então começar a editar.


3. Pontos-Chave

(1) Uso Básico do grep

BASH
# Busca básica
grep "padrão" arquivo

# Combinações comuns de opções
grep -rn "TODO" src/      # Busca recursiva, mostra números de linha
grep -i "erro" log.txt    # Ignorar maiúsculas/minúsculas
grep -v "debug" log.txt   # Inverter correspondência (linhas que NÃO contêm debug)
grep -c "falhou" log.txt  # Contar apenas
grep -l "main" *.py       # Mostrar apenas nomes de arquivos que correspondem
grep -A5 -B5 "exception" log.txt # Mostrar 5 linhas antes e depois da correspondência
Opção Significado
-i Ignorar maiúsculas/minúsculas
-v Inverter correspondência (mostrar linhas que não correspondem)
-c Apenas a quantidade de linhas correspondentes
-n Mostrar números de linha
-r ou -R Busca recursiva em subdiretórios
-l Mostrar apenas nomes de arquivos que contêm correspondências
-L Mostrar apenas nomes de arquivos que NÃO contêm correspondências
-w Correspondência de palavras inteiras
-A NUM Mostrar NUM linhas após a correspondência
-B NUM Mostrar NUM linhas antes da correspondência
-C NUM Mostrar NUM linhas antes e depois da correspondência

(2) Expressões Regulares Básicas

Metacaractere Significado Exemplo
. Corresponde a qualquer caractere único h.t corresponde a hit / hot / hat
^ Início da linha ^root corresponde a linhas que começam com root
$ Fim da linha bash$ corresponde a linhas que terminam com bash
* Caractere anterior repetido 0 ou mais vezes ab*c corresponde a ac / abc / abbc
[abc] Qualquer caractere do conjunto [Hh]ello corresponde a Hello ou hello
[^abc] Caracteres que NÃO estão no conjunto [^0-9] corresponde a caracteres não numéricos
\< Início de palavra \<root corresponde a root no início de uma palavra
\> Fim de palavra root\> corresponde a root no fim de uma palavra
💡 Dica: O regex . corresponde a qualquer caractere único — se precisar corresponder a um ponto literal (como em um endereço IP), você precisa escapá-lo com barra invertida: grep "192\.168\." arquivo em vez de grep "192.168." arquivo (o último corresponderia incorretamente a 192X168Y etc.).

(3) Expressões Regulares Estendidas (grep -E)

No regex básico, +, ?, |, {}, () precisam ser escapados. O regex estendido usa esses metacaracteres diretamente (via grep -E ou egrep):

ℹ️ Nota: A principal diferença entre regex básico e estendido é que no regex estendido (grep -E), +, ?, |, {}, () podem ser usados sem escape com barra invertida. No regex básico, grep "error\|warning" requer escape de |, enquanto grep -E "error|warning" não requer. Prefira grep -E para uma sintaxe mais clara.

Metacaractere Significado Exemplo
+ Caractere anterior repetido 1 ou mais vezes ab+c corresponde a abc / abbc mas não a ac
? Caractere anterior aparece 0 ou 1 vez colou?r corresponde a color ou colour
` ` Ou
{n,m} Repetir n a m vezes [0-9]{3,5} corresponde a números de 3-5 dígitos
() Agrupamento `(error

(4) ▶ Exemplo: Busca Básica

BASH
# Buscar em um arquivo
grep "root" /etc/passwd
# root:x:0:0:root:/root:/bin/bash

# Ignorar maiúsculas/minúsculas
echo -e "Erro\nerro\nERRO" | grep -i "erro"
# Todas as três linhas correspondem

# Contar
grep -c "nologin" /etc/passwd
# Saída: 16

# Mostrar números de linha
grep -n "www-data" /etc/passwd
# 33:www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin

Saída:

TEXT
root:x:0:0:root:/root:/bin/bash
Erro
erro
ERRO
16
33:www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin

(5) ▶ Exemplo: Inverter Correspondência

BASH
# Excluir linhas de comentário
grep -v "^#" /etc/ssh/sshd_config | grep -v "^$"

# Excluir logs de debug
grep -v "DEBUG" app.log | grep "ERROR"

# Excluir arquivos com certas extensões
ls -la | grep -v "\.md$"

Saída:

TEXT
Port 22
PermitRootLogin no
PasswordAuthentication no
2026-07-07 10:23:45 ERROR Database connection failed
2026-07-07 10:24:12 ERROR Timeout waiting for response
drwxr-xr-x 2 alice alice 4096 Jul  7 10:00 src
-rw-r--r-- 1 alice alice 1234 Jul  7 10:00 config.yaml

(6) ▶ Exemplo: Busca Recursiva em Código

BASH
# Buscar todos os comentários TODO no projeto
grep -rn "TODO\|FIXME\|HACK" --include="*.py" src/

# Buscar em tipos específicos de arquivo
grep -rn "def " --include="*.py" --include="*.js" .

# Buscar excluindo node_modules
grep -rn "api_key" --exclude-dir=node_modules --exclude-dir=.git .

# Mostrar apenas nomes de arquivos
grep -rl "class User" src/

Saída:

TEXT
src/api/client.py:23:# TODO: Add retry logic
src/models/user.py:45:# FIXME: Handle edge case
src/utils/helpers.py:12:# HACK: Temporary workaround
src/api/client.py:10:def get_user(user_id):
src/models/user.py:5:def validate_email(email):
config/settings.py:3:api_key = "sk-xxx"
src/models/user.py
src/auth.py
💡 Dica: grep -rn é a combinação de ouro para busca em código — -r busca recursivamente em diretórios, -n mostra números de linha e --include limita os tipos de arquivo. Em projetos grandes, grep -rn "padrão" --include="*.py" src/ consegue localizar o código alvo em um segundo.

(7) ▶ Exemplo: Usando Contexto

BASH
# Mostrar 3 linhas antes e depois da correspondência
grep -C 3 "NullPointerException" app.log

# Mostrar 5 linhas após a correspondência
grep -A 5 "Traceback" python_error.log

# Mostrar 2 linhas antes da correspondência
grep -B 2 "500" access.log

Saída:

TEXT
10:23:01 INFO Processing request
10:23:02 WARN Memory usage high
10:23:03 ERROR NullPointerException at UserService.java:45
10:23:04 INFO Retrying operation
10:23:05 WARN Connection pool low
Traceback (most recent call last):
  File "app.py", line 42, in handle_request
    result = process(data)
  File "processor.py", line 15, in process
    return transform(input)
ValueError: Invalid input data
192.168.1.100 - - [07/Jul/2026:10:23:44] "POST /api/data"
192.168.1.100 - - [07/Jul/2026:10:23:45] "POST /api/data HTTP/1.1" 500 0

(8) ▶ Exemplo: Regex na Prática

BASH
# Corresponder endereços de e-mail
grep -E "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}" contatos.txt

# Corresponder endereços IP
grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" access.log

# Corresponder URLs
grep -E "https?://[^ ]+" index.html

# Corresponder datas (YYYY-MM-DD)
grep -E "[0-9]{4}-[0-9]{2}-[0-9]{2}" logs/*.log

# Corresponder linhas que começam com dígito e terminam com letra
grep "^[0-9].*[a-zA-Z]$" arquivo.txt

Saída:

TEXT
alice@example.com
bob.smith@company.org
contact@my-site.net
192.168.1.100 - - [07/Jul/2026] ...
10.0.0.45 - - [07/Jul/2026] ...
https://example.com/api/users
http://internal.server.local/status
2026-07-07
2026-07-08
1abc
23x

(9) ▶ Exemplo Abrangente: Análise de Erros em Log

BASH
#!/bin/bash
# analyze-errors.sh - Análise de erros em log

LOG_FILE="${1:-/var/log/syslog}"

echo "=== Relatório de Análise de Erros ==="
echo "Arquivo de origem: $LOG_FILE"
echo ""

echo "1. Contagem de erros por tipo:"
grep -i "erro" "$LOG_FILE" | awk '{print $5}' | sort | uniq -c | sort -rn | head -10

echo ""
echo "2. Últimos 5 erros:"
grep -i "erro" "$LOG_FILE" | tail -5

echo ""
echo "3. Alertas críticos (OOM / Disco cheio / Conexão recusada):"
grep -iE "oom|out of memory|disk full|no space left|connection refused" "$LOG_FILE"

echo ""
echo "4. Tendência de erros (por hora):"
grep -i "erro" "$LOG_FILE" | grep -oP "\d{2}:\d{2}" | cut -d: -f1 | sort | uniq -c | sort -rn

❓ Perguntas Frequentes

P: Qual é a diferença entre grep e regex? R: grep é uma ferramenta de linha de comando para buscar linhas que correspondem a um padrão em arquivos; expressões regulares (regex) são uma sintaxe para descrever padrões de texto. O grep suporta regex como padrões de busca, mas regex em si é apenas uma sintaxe que também pode ser usada em sed, awk, Python e muitas outras ferramentas e linguagens.

P: grep -r e grep -R são a mesma coisa? R: Basicamente sim. -R segue links simbólicos, enquanto -r não por padrão. Qualquer um serve para uso diário.

P: Como faço para buscar ignorando maiúsculas/minúsculas? R: Use a opção -i: grep -ir "erro" /var/log/.

P: Por que o grep às vezes não encontra caracteres chineses? R: Pode ser um problema de localidade. Caracteres chineses são multibyte em UTF-8, e o grep corresponde por byte por padrão. Tente export LANG=zh_CN.UTF-8 ou grep -P (modo regex Perl).

P: Para que serve grep -v? R: Inverter correspondência — produz linhas que NÃO correspondem ao padrão. Combinado com outras chamadas de grep, pode "excluir" certas linhas, por exemplo, grep -v "^#" exclui linhas de comentário, grep -v "^$" exclui linhas em branco.


📖 Resumo


📝 Exercícios

  1. Básico (Dificuldade ⭐): Busque em /etc/passwd usuários que tenham /bin/bash como seu shell de login, depois busque erros em um arquivo de log e use -c para contá-los
  2. Intermediário (Dificuldade ⭐⭐): Busque recursivamente em um diretório de projeto por todos os comentários FIXME e TODO, depois use grep -v para excluir o diretório .git e contar o total de linhas de código
  3. Avançado (Dificuldade ⭐⭐⭐): Use regex para corresponder todos os endereços IP em um arquivo de log, depois combine sort e uniq -c para contar ocorrências por IP e encontre os 10 IPs mais frequentes
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%