O comando grep é uma ferramenta essencial no shell Linux/Bash para buscar padrões em arquivos ou na saída de outros comandos. Ele permite filtrar linhas que correspondem a um padrão especificado, sendo amplamente utilizado em scripts e no dia a dia do administrador de sistemas. Nesta aula, você aprenderá desde os usos mais simples até técnicas avançadas com expressões regulares.

Dominar o grep aumenta significativamente sua produtividade no terminal, pois você pode rapidamente encontrar informações em logs, configurar scripts de monitoramento e processar texto de forma eficiente. Vamos explorar os padrões básicos, flags úteis, regex e casos de uso práticos.

Padrões básicos

A sintaxe básica do grep é: grep [opções] padrão [arquivo...]. O padrão é uma string ou expressão regular que será procurada em cada linha do(s) arquivo(s) ou da entrada padrão (stdin). Se nenhum arquivo for fornecido, o grep lê da entrada padrão, permitindo uso em pipes.

Exemplo simples: buscar a palavra "erro" em um arquivo de log.

grep "erro" /var/log/syslog

Isso exibirá todas as linhas que contêm a string "erro". O padrão é interpretado como literal, a menos que você use expressões regulares. Você também pode buscar em múltiplos arquivos:

grep "warning" *.log

Isso procura "warning" em todos os arquivos com extensão .log no diretório atual. O nome do arquivo é exibido antes da linha correspondente.

Flags (-i, -v, -r, -n)

O grep possui diversas flags que modificam seu comportamento. As mais comuns são:

  • -i: ignora diferenças entre maiúsculas e minúsculas (case-insensitive).
  • -v: inverte a correspondência, exibindo linhas que NÃO contêm o padrão.
  • -r ou -R: busca recursivamente em diretórios.
  • -n: exibe o número da linha junto com a linha correspondente.

Exemplo com -i: buscar "error" ignorando caixa:

grep -i "error" /var/log/syslog

Exemplo com -v: exibir linhas que NÃO contêm "#" (comentários) em um arquivo de configuração:

grep -v "#" /etc/ssh/sshd_config

Exemplo com -r: buscar recursivamente por "TODO" em todos os arquivos de um diretório:

grep -r "TODO" /home/user/projeto/

Exemplo com -n: mostrar números de linha ao buscar "import" em um script Python:

grep -n "import" script.py

Você pode combinar flags, como grep -rin "palavra" /caminho para busca recursiva, case-insensitive e com números de linha.

grep com regex

O grep aceita expressões regulares (regex) para padrões mais complexos. Por padrão, ele usa regex básicas (BRE), mas com a flag -E você usa regex estendidas (ERE), que oferecem mais operadores. Alternativamente, use egrep (equivalente a grep -E).

Exemplos de regex básicas:

  • ^: início da linha. Ex: grep "^#" arquivo → linhas que começam com #.
  • $: fim da linha. Ex: grep "$" (pouco útil sozinho, mas grep "^$" encontra linhas vazias).
  • .: qualquer caractere (exceto nova linha). Ex: grep "c.t" arquivo → linhas com "cat", "cot", etc.
  • *: zero ou mais do caractere anterior. Ex: grep "ab*c" → "ac", "abc", "abbc", etc.
  • []: conjunto de caracteres. Ex: grep "[0-9]" → linhas contendo dígitos.

Com regex estendidas (-E), você tem operadores adicionais:

  • +: um ou mais do anterior.
  • ?: zero ou um do anterior.
  • |: alternância (ou).
  • (): agrupamento.

Exemplo: buscar linhas que contenham "erro" ou "warning":

grep -E "erro|warning" /var/log/syslog

Exemplo: buscar linhas com números de telefone no formato (XX) XXXX-XXXX:

grep -E "\([0-9]{2}\) [0-9]{4}-[0-9]{4}" agenda.txt

Note que os parênteses e espaços precisam ser escapados ou usados com cuidado. O grep também suporta a flag -P para regex Perl-compatible (PCRE), que é ainda mais poderosa, mas nem sempre disponível em todas as versões.

Casos de uso

O grep é extremamente versátil. Aqui estão alguns casos de uso comuns:

  • Filtrar logs: grep "FAILED" /var/log/auth.log para encontrar tentativas de login falhas.
  • Encontrar processos: ps aux | grep "nginx" para listar processos relacionados ao nginx.
  • Buscar em código-fonte: grep -rn "funcao" /src/ para localizar definições ou usos de uma função.
  • Verificar configurações: grep "^Port" /etc/ssh/sshd_config para ver a porta configurada.
  • Contar ocorrências: grep -c "erro" arquivo.log conta quantas linhas contêm "erro".
  • Extrair IPs: grep -E -o "([0-9]{1,3}\.){3}[0-9]{1,3}" arquivo extrai endereços IP.

Exemplo prático: monitorar logs em tempo real com tail -f e grep:

tail -f /var/log/nginx/access.log | grep "404"

Isso exibirá apenas as linhas de acesso com erro 404 conforme aparecem.

Boas práticas

Ao usar grep, lembre-se de:

  • Usar aspas no padrão para evitar que o shell interprete caracteres especiais.
  • Utilizar --color=auto para destacar as correspondências (muitas distribuições já têm alias).
  • Combinar grep com outros comandos via pipe para análises mais complexas.
  • Preferir grep -F (fixed strings) quando o padrão não for regex, para maior desempenho.

Referências

Exercícios

  1. Crie um comando grep para listar todas as linhas do arquivo /etc/passwd que contenham o shell /bin/bash.

    ✓ Resposta:
    grep "/bin/bash" /etc/passwd
  2. Usando a flag -v, exiba as linhas do arquivo config.txt que não estão comentadas (não começam com #).

    ✓ Resposta:
    grep -v "^#" config.txt
  3. Faça uma busca recursiva (com -r) e case-insensitive (com -i) pela palavra "TODO" em todos os arquivos do diretório /home/user/projeto, mostrando também os números das linhas.

    ✓ Resposta:
    grep -rin "TODO" /home/user/projeto
  4. Utilize expressão regular estendida (-E) para encontrar linhas no arquivo arquivo.txt que contenham um número de telefone no formato (99) 9999-9999 (onde 9 é um dígito).

    ✓ Resposta:
    grep -E "\([0-9]{2}\) [0-9]{4}-[0-9]{4}" arquivo.txt
  5. Conte quantas vezes a palavra "error" aparece (linhas que a contêm) no arquivo /var/log/syslog.

    ✓ Resposta:
    grep -c "error" /var/log/syslog