Ubuntu grep
O find procura arquivos; o grep procura texto dentro dos arquivos. Ele lê linha por linha e mostra só as linhas que contêm o que você pediu. É a ferramenta para achar um erro num log de milhares de linhas, uma configuração esquecida ou um nome numa lista.
- Como o
grepfunciona: um filtro de linhas. - As opções do dia a dia:
-i,-n,-c,-v,-w,-r,-l,-o. - Expressões regulares básicas:
^,$,.,[ ],|. - Usar o
grepno meio de um pipe, e a armadilha dops aux | grep. - O que significa quando o
grepnão mostra nada.
O nome vem de um comando antigo do editor ed: g/re/p, ou global / regular expression / print, "em todo o arquivo, procure a expressão e mostre".
O arquivo de exemplo
Nesta aula vamos usar o log de um pequeno site, Documentos/acesso.log. Cada linha é uma visita: quem visitou (IP), quando, qual página e o resultado (200 = deu certo, 403 = proibido, 404 = não encontrado).
$ cat Documentos/acesso.log 192.168.0.10 - - [15/Oct/2026:09:01:12] "GET / HTTP/1.1" 200 192.168.0.23 - - [15/Oct/2026:09:01:40] "GET /contato HTTP/1.1" 200 192.168.0.10 - - [15/Oct/2026:09:02:03] "GET /admin HTTP/1.1" 403 192.168.0.57 - - [15/Oct/2026:09:05:19] "GET /fotos HTTP/1.1" 404 192.168.0.10 - - [15/Oct/2026:09:06:44] "POST /login HTTP/1.1" 200 192.168.0.23 - - [15/Oct/2026:09:07:02] "GET / HTTP/1.1" 200
A forma mais simples
- grep
- O programa: filtra linhas.
- 403
- O padrão: o texto que a linha precisa conter.
- Documentos/acesso.log
- O arquivo onde procurar.
$ grep 403 Documentos/acesso.log 192.168.0.10 - - [15/Oct/2026:09:02:03] "GET /admin HTTP/1.1" 403
De seis linhas, só uma contém 403, e é a única que aparece. No seu terminal, o trecho encontrado aparece em vermelho: o Ubuntu já vem com o atalho alias grep='grep --color=auto' no ~/.bashrc.
grep GET /admin acesso.log procuraria "GET" nos arquivos /admin e acesso.log. O certo é grep "GET /admin" acesso.log. Na dúvida, coloque o padrão sempre entre aspas.
Missão: descubra qual página deu erro 404 (página não encontrada) no arquivo Documentos/acesso.log.
Uma opção por vez
-i: ignorar maiúsculas
Por padrão, Banana e banana são diferentes. Com -i (de ignore case), não:
$ grep BANANA frutas.txt $ grep -i BANANA frutas.txt banana banana banana
-n: mostrar o número da linha
Útil para abrir o arquivo no editor direto na linha certa (no nano: nano +3 arquivo).
$ grep -n admin Documentos/acesso.log 3:192.168.0.10 - - [15/Oct/2026:09:02:03] "GET /admin HTTP/1.1" 403 « linha 3
-c: só contar
Em vez de mostrar as linhas, mostra quantas combinam (de count):
$ grep -c 192.168.0.10 Documentos/acesso.log 3
-v: inverter (o que NÃO contém)
Mostra as linhas que não combinam. Aqui, tudo o que não deu 200, ou seja, só os problemas:
- grep
- O programa.
- -v
- Inverte: mostra as linhas que não contêm o padrão.
- " 200"
- O padrão, com um espaço antes para não pegar "2000" por engano.
- Documentos/acesso.log
- O arquivo.
$ grep -v " 200" Documentos/acesso.log 192.168.0.10 - - [15/Oct/2026:09:02:03] "GET /admin HTTP/1.1" 403 192.168.0.57 - - [15/Oct/2026:09:05:19] "GET /fotos HTTP/1.1" 404
-w: palavra inteira
O grep acha o padrão em qualquer lugar da linha, até no meio de uma palavra. Procurando "ana" em frutas.txt:
$ grep ana frutas.txt banana « "ana" está dentro de "banana" banana banana $ grep -w ana frutas.txt $ echo $? 1 « nenhuma linha tem a palavra "ana" sozinha
Com -w (de word), o padrão precisa ser uma palavra inteira, separada por espaço ou pontuação.
-o: só o trecho encontrado
Em vez da linha inteira, mostra só o pedaço que combinou (de only matching). Ótimo para extrair dados:
$ grep -o "192.168.0.[0-9]*" Documentos/acesso.log 192.168.0.10 192.168.0.23 192.168.0.10 192.168.0.57 192.168.0.10 192.168.0.23
-A, -B, -C: linhas ao redor
Num log, a linha do erro nem sempre basta: você quer ver o que veio antes e depois. -A 2 mostra 2 linhas depois (after), -B 2 mostra 2 antes (before) e -C 2 mostra 2 de cada lado (context).
$ grep -A1 João Documentos/notas.txt Ligar para o João Estudar Ubuntu « a linha seguinte $ grep -n -B1 Ubuntu Documentos/notas.txt 2-Ligar para o João « "-" = linha de contexto 3:Estudar Ubuntu « ":" = linha que combinou
Procurar em vários arquivos
Vários arquivos de uma vez
Com mais de um arquivo, cada linha vem com o nome do arquivo na frente:
$ grep -c banana frutas.txt Documentos/notas.txt frutas.txt:3 Documentos/notas.txt:0
-r: procurar dentro de uma pasta inteira
- grep
- O programa.
- -r
- Recursivo: entra em todas as subpastas (de recursive).
- "Ubuntu"
- O texto a procurar.
- Documentos
- A pasta onde começar.
$ grep -r "Ubuntu" Documentos Documentos/notas.txt:Estudar Ubuntu
-l: só o nome dos arquivos
Quando você só quer saber quais arquivos contêm o texto (de list):
$ grep -rl "Olá" Documentos Documentos/projetos/site/index.html
Um uso real: descobrir em qual arquivo de configuração está uma opção.
$ grep -rn "PasswordAuthentication" /etc/ssh/ 2>/dev/null /etc/ssh/ssh_config:25:# PasswordAuthentication yes
Resposta: arquivo /etc/ssh/ssh_config, linha 25. O # no começo indica que a linha está comentada (desativada).
Missão: salve num arquivo erros.txt todas as linhas de Documentos/acesso.log que não terminaram com 200. Dica: grep -v … > erros.txt. Depois confira com cat erros.txt.
Expressões regulares básicas
O padrão do grep não é só texto: é uma expressão regular (regex), uma pequena linguagem para descrever textos. Alguns caracteres têm significado especial:
| Símbolo | Significa | Exemplo | Combina com |
|---|---|---|---|
. | Qualquer caractere (um só) | b.n | ban, bin, b9n |
* | O anterior repetido 0 ou mais vezes | 10* | 1, 10, 1000 |
^ | Começo da linha | ^b | linhas que começam com b |
$ | Fim da linha | a$ | linhas que terminam com a |
[abc] | Um dos caracteres da lista | [bm] | b ou m |
[0-9] | Uma faixa | [0-9][0-9] | dois dígitos |
[^0-9] | Qualquer um, menos os da lista | [^a-z] | o que não é letra minúscula |
\. | Um ponto de verdade | \.txt$ | termina em ".txt" |
$ grep "^[bm]" frutas.txt # começa com b ou m banana maçã banana maçã banana $ grep "a$" frutas.txt # termina com a banana laranja banana uva banana
-E: regex estendida (com "ou")
Com -E (de extended), você ganha | ("ou"), + (1 ou mais), ? (opcional) e parênteses para agrupar, sem precisar de barras:
- grep
- O programa.
- -E
- Usa a regex estendida.
- "40[34]$"
- "40", depois 3 ou 4, no fim da linha: pega 403 e 404.
- Documentos/acesso.log
- O arquivo.
$ grep -E "40[34]$" Documentos/acesso.log 192.168.0.10 - - [15/Oct/2026:09:02:03] "GET /admin HTTP/1.1" 403 192.168.0.57 - - [15/Oct/2026:09:05:19] "GET /fotos HTTP/1.1" 404 $ grep -E "POST|admin" Documentos/acesso.log 192.168.0.10 - - [15/Oct/2026:09:02:03] "GET /admin HTTP/1.1" 403 192.168.0.10 - - [15/Oct/2026:09:06:44] "POST /login HTTP/1.1" 200
Use -F (de fixed, "fixo"). Assim grep -F "1.1" arquivo procura "1.1" de verdade, e o ponto não vira "qualquer caractere".
Missão: usando ^, mostre só as frutas de frutas.txt que começam com a letra l ou u.
grep no meio de um pipe
O grep também filtra a saída de outros comandos. O | (pipe) entrega a saída do primeiro como entrada do segundo (veja Pipes e xargs):
$ ls -l | grep frutas -rw-rw-r-- 1 ana ana 47 Oct 14 16:05 frutas.txt $ history | grep apt 12 sudo apt update 13 sudo apt install htop
A armadilha do ps aux | grep
Procurando um programa na lista de processos, o próprio grep aparece no resultado:
$ ps aux | grep chrome ana 2210 5.4 6.8 1100000 1093000 ? Sl 08:00 0:16 /snap/chromium/3554/usr/lib/chromium-browser/chrome --password-store ana 2251 2.0 3.9 636000 629000 ? Sl 08:00 0:06 /snap/chromium/3554/usr/lib/chromium-browser/chrome --type=renderer ana 3305 0.0 0.0 9284 2304 pts/0 S+ 10:30 0:00 grep --color=auto chrome « o próprio grep!
Isso acontece porque, no momento em que o ps tira a foto dos processos, o grep chrome já está rodando, e a linha de comando dele contém "chrome". Duas saídas:
- Use
pgrep -a chrome, feito exatamente para isso (veja ps, pgrep, top). - Ou o truque
ps aux | grep "[c]hrome": a regex[c]hromecombina com "chrome", mas a linha do grep contém "[c]hrome", que não combina com ela mesma.
O que o grep devolve
O grep é um dos poucos comandos em que o código de saída diz se ele achou algo:
| Código | Significado |
|---|---|
0 | Achou pelo menos uma linha |
1 | Não achou nada (não é erro!) |
2 | Houve erro: arquivo inexistente, regex inválida… |
$ grep uva frutas.txt uva $ echo $? 0 $ grep abacaxi frutas.txt $ echo $? 1 « silêncio + 1 = não achou $ grep uva frutas.text grep: frutas.text: Arquivo ou diretório inexistente $ echo $? 2
Em scripts, use -q (de quiet, "quieto"): não mostra nada, só devolve o código.
$ grep -q "Ubuntu" /etc/os-release && echo "É Ubuntu!" É Ubuntu!
Formas diferentes de fazer
Contar linhas que combinam
$ grep -c banana frutas.txt 3 $ grep banana frutas.txt | wc -l 3
Os dois dão o mesmo resultado. O -c é mais curto; o | wc -l funciona com qualquer comando no lugar do grep.
Procurar em muitos arquivos
| Forma | Exemplo | Melhor quando… |
|---|---|---|
grep -r | grep -rn "erro" ~/projeto | Quer procurar em tudo dentro de uma pasta. É a forma mais simples. |
grep -r --include | grep -rn --include="*.py" "def " . | Quer só certos tipos de arquivo. |
find … -exec grep | find . -name "*.log" -mtime -1 -exec grep -H erro {} + | Precisa dos filtros do find, como data e tamanho. |
find … | xargs grep | find . -name "*.conf" -print0 | xargs -0 grep -l porta | Mesmo caso; forma clássica em scripts. |
Procurar um processo
| Forma | Diferença |
|---|---|
ps aux | grep chrome | Mostra tudo do processo, mas inclui o próprio grep. |
pgrep -a chrome | Mostra PID e linha de comando, sem a armadilha. |
Quando não funciona
$ grep Banana frutas.txt $
O que aconteceu: nenhuma linha tem "Banana" com B maiúsculo. Silêncio no grep não é erro: só quer dizer "não achei" (código 1).
Como confirmar: echo $? mostra 1. Se mostrar 2, é erro de verdade.
Como resolver: tente -i, confira a grafia (acentos contam: "maca" não acha "maçã") e se o arquivo é o certo.
$ grep Ubuntu Documentos grep: Documentos: É um diretório
Como resolver: para procurar dentro da pasta, use -r: grep -r Ubuntu Documentos.
$ grep 403 acesso.log grep: acesso.log: Arquivo ou diretório inexistente
O que aconteceu: o arquivo está em outra pasta (Documentos/acesso.log). Também acontece quando o padrão tem espaço e está sem aspas: a segunda palavra vira "arquivo".
$ grep -E "(erro" app.log grep: ( ou \( descasados
O que aconteceu: na regex, ( abre um grupo que nunca foi fechado.
Como resolver: para procurar o caractere ( literalmente, use -F: grep -F "(erro" app.log.
$ grep ELF /usr/bin/bash grep: /usr/bin/bash: arquivo binário coincide com o padrão
O que aconteceu: o arquivo não é texto (é um programa, imagem, PDF…). O grep avisa que achou, mas não imprime a linha para não sujar o terminal.
Como resolver: normalmente não há o que resolver. Se precisar mesmo, grep -a trata o arquivo como texto.
Referência de opções
| Opção | Descrição | Exemplo |
|---|---|---|
-i | Ignora maiúsculas e minúsculas | grep -i erro log |
-n | Mostra o número da linha | grep -n erro log |
-c | Conta as linhas que combinam | grep -c erro log |
-v | Mostra as que não combinam | grep -v "^#" config |
-w | Só palavras inteiras | grep -w ana lista |
-x | Só se a linha inteira for igual ao padrão | grep -x uva frutas.txt |
-o | Mostra só o trecho encontrado | grep -o "[0-9]*" arq |
-r / -R | Procura dentro de pastas (-R segue links) | grep -r senha /etc |
-l | Só os nomes dos arquivos que combinam | grep -rl TODO . |
-L | Só os nomes dos que não combinam | grep -L licença *.py |
-h / -H | Esconde / mostra o nome do arquivo | grep -h erro *.log |
-A N / -B N / -C N | N linhas depois / antes / ao redor | grep -C 2 erro log |
-E | Regex estendida (| + ? ()) | grep -E "403|404" log |
-F | Texto fixo, sem regex | grep -F "a.b" arq |
-q | Silencioso: só o código de saída | grep -q x arq && echo sim |
-s | Esconde mensagens de erro de arquivos | grep -s x * |
--include | Com -r, só arquivos com esse nome | --include="*.conf" |
--color=auto | Destaca o trecho (já ativo no Ubuntu) | — |
Exercícios
1. Contar ocorrências
Complete para mostrar quantas linhas de acesso.log contêm GET:
2. Sem os comentários
Em arquivos de configuração, linhas que começam com # são comentários. Complete para mostrar só as linhas que não começam com #:
3. Pasta inteira com número da linha
Complete para procurar "senha" em todos os arquivos dentro de ~/projeto, mostrando o número da linha:
4. grep erro app.log não mostrou nada e echo $? mostrou 1. O que isso significa?
5. Qual padrão acha linhas que terminam em ".conf"?
Resumo
grep padrão arquivomostra as linhas que contêm o padrão; coloque o padrão entre aspas.- As opções mais usadas:
-i(maiúsculas),-n(número),-c(contar),-v(inverter),-r(pasta),-l(só nomes). ^= começo,$= fim,.= qualquer caractere,[ ]= um da lista;-Elibera o|.- Código 0 = achou, 1 = não achou, 2 = erro.
- Em
ps aux | grep, o próprio grep aparece; prefirapgrep -a.