Comando find do Linux: opções -name, -type, -size, -mtime e -delete
O comando find do Linux percorre uma pasta inicial para baixo e encontra arquivos e pastas que atendem a condições como nome, tipo, tamanho, horário de modificação e permissões. Ao criar dez arquivos em uma pasta de teste de um servidor AlmaLinux 9 e executá-lo mudando uma condição por vez, acabamos passando os arquivos encontrados com -exec a outros comandos e, ao excluir, conferindo antes a lista com as mesmas condições, antes de -delete.
Os caminhos da pasta de teste e os horários dos arquivos nas caixas de resultado foram trocados por valores de exemplo. Na saída do servidor Debian 12, apenas o caminho da pasta home é valor de exemplo, e o restante está como saiu.
1️⃣ Como usar o comando find do Linux
A forma básica é [find caminho-inicial condições]. Sem o caminho inicial, ele busca na pasta atual (.), e sem condições imprime todos os arquivos e pastas sob o caminho inicial.
O teste foi feito em /root/work, com três pastas e dez arquivos como abaixo.
find /root/work/root/work
/root/work/docs
/root/work/docs/readme.txt
/root/work/docs/guide.txt
/root/work/docs/old.tmp
/root/work/logs
/root/work/logs/app.log
/root/work/logs/cache.tmp
/root/work/backup
/root/work/report.txt
/root/work/README.md
/root/work/run.sh
/root/work/my notes.txt
/root/work/empty.txtO find não ordena os resultados por nome; nesta execução, ao chegar à pasta docs, imprimiu primeiro todos os arquivos dela e depois passou para logs.
Se você encadear várias condições, só ficam os arquivos que atendem a todas.
-name compara com o padrão apenas o nome do arquivo, não o caminho. Coloque o padrão entre aspas simples para que o shell não expanda * antes e o passe como está ao find.
find /root/work -name '*.txt'/root/work/docs/readme.txt
/root/work/docs/guide.txt
/root/work/report.txt
/root/work/my notes.txt
/root/work/empty.txt-name diferencia maiúsculas de minúsculas. Ao buscar nomes que começam com readme, só veio docs/readme.txt, e com -iname veio também README.md.
find /root/work -name 'readme*'/root/work/docs/readme.txtfind /root/work -iname 'readme*'/root/work/docs/readme.txt
/root/work/README.mdO find faz parte do pacote findutils. A versão na primeira linha de [find --version] foi findutils 4.8 no servidor AlmaLinux 9.8 e 4.9 no servidor Debian 12.
2️⃣ find -type d e -maxdepth
-type f deixa só arquivos comuns e -type d só pastas.
find /root/work -type d/root/work
/root/work/docs
/root/work/logs
/root/work/backupO caminho inicial /root/work também é uma pasta, por isso apareceu na primeira linha. Com -type f no mesmo caminho, apareceram os dez arquivos.
-maxdepth define quantos níveis descer a partir do caminho inicial. Com -maxdepth 1, os arquivos de docs e logs saíram, e só ficaram os cinco arquivos logo abaixo de /root/work.
find /root/work -maxdepth 1 -type f/root/work/report.txt
/root/work/README.md
/root/work/run.sh
/root/work/my notes.txt
/root/work/empty.txtAo contrário, -mindepth 2 pulou o que está logo abaixo do caminho inicial e imprimiu só os cinco arquivos dentro de subpastas.
find /root/work -mindepth 2 -type f/root/work/docs/readme.txt
/root/work/docs/guide.txt
/root/work/docs/old.tmp
/root/work/logs/app.log
/root/work/logs/cache.tmpA página man orienta escrever opções globais como -maxdepth logo depois do caminho inicial. Escrever -maxdepth 1 depois de -type f também deu os mesmos cinco arquivos, mas no terminal aparece uma linha de aviso pedindo para colocar as opções globais antes (conforme a página man).
Para ver só quantas pastas ou arquivos existem, passe a saída para wc -l. A contagem da saída de -type d deu 4, incluindo o caminho inicial.
find /root/work -type d | wc -l4Com -maxdepth 1 também deu 4, porque as três subpastas estão logo abaixo do caminho inicial.
find /root/work -maxdepth 1 -type d | wc -l4Contar com -mindepth 2 só os arquivos dentro de subpastas deu 5.
find /root/work -mindepth 2 -type f | wc -l53️⃣ Condições de tamanho e tempo do comando find
O + antes do número significa maior que esse valor, - significa menor, e sem sinal é exatamente esse valor. As unidades de -size estão na tabela abaixo (conforme a página man).
| Unidade | Tamanho | Sim |
|---|---|---|
| c | 1 byte | -size +500c |
| k | 1,024 bytes | -size +1k |
| M | 1,048,576 bytes | -size +1M |
| G | 1,073,741,824 bytes | -size +1G |
| (nenhuma) | Blocos de 512 bytes | -size +2 |
find /root/work -type f -size +1k/root/work/docs/guide.txt
/root/work/logs/app.log
/root/work/report.txtOs arquivos maiores que 1k foram guide.txt com 5,000 bytes, app.log com 2MB e report.txt com 1,200 bytes.
find /root/work -size +1M/root/work/logs/app.logAo escrever -size duas vezes para definir uma faixa, só ficaram os dois arquivos maiores que 1k e menores que 100k.
find /root/work -type f -size +1k -size -100k/root/work/docs/guide.txt
/root/work/report.txt-size divide o tamanho pela unidade e arredonda para cima antes de comparar. Por isso README.md, com 300 bytes, também conta como 1k, e com -size -1k só veio empty.txt, de tamanho 0.
find /root/work -type f -size -1k/root/work/empty.txtPara testar as condições de tempo, ajustamos o horário de modificação de README.md, my notes.txt e docs/readme.txt para 3 dias atrás e o dos dois arquivos .tmp para 10 dias atrás. Cada arquivo guarda três horários, de acesso, modificação e alteração, que você pode consultar com o comando stat.
-mtime conta o tempo desde a última modificação em unidades de 24 horas. Com -mtime -1 vieram os cinco arquivos criados nas últimas 24 horas.
find /root/work -type f -mtime -1/root/work/docs/guide.txt
/root/work/logs/app.log
/root/work/report.txt
/root/work/run.sh
/root/work/empty.txtCom -mtime +7 vieram só os dois arquivos .tmp ajustados para 10 dias atrás. Use esta forma para conferir a lista antes de excluir logs antigos ou arquivos temporários.
find /root/work -type f -mtime +7/root/work/docs/old.tmp
/root/work/logs/cache.tmp-mmin faz o mesmo cálculo em minutos. O resultado de -mmin -60 foram os mesmos cinco arquivos de -mtime -1.
find /root/work -type f -mmin -60/root/work/docs/guide.txt
/root/work/logs/app.log
/root/work/report.txt
/root/work/run.sh
/root/work/empty.txt-newer encontra arquivos modificados depois de um arquivo de referência. Com README.md, ajustado para 3 dias atrás, como referência, vieram os cinco arquivos criados depois.
find /root/work -type f -newer /root/work/README.md/root/work/docs/guide.txt
/root/work/logs/app.log
/root/work/report.txt
/root/work/run.sh
/root/work/empty.txt-empty encontra ao mesmo tempo arquivos de tamanho 0 e pastas vazias, e vieram a pasta vazia backup e empty.txt.
find /root/work -empty/root/work/backup
/root/work/empty.txt4️⃣ Condições -perm e -user do find
Com apenas um número depois de -perm, ele busca arquivos com permissão exatamente nesse valor. Com -perm 644 ficaram de fora run.sh, com 755, e my notes.txt, com 600, e vieram oito arquivos.
find /root/work -type f -perm 644/root/work/docs/readme.txt
/root/work/docs/guide.txt
/root/work/docs/old.tmp
/root/work/logs/app.log
/root/work/logs/cache.tmp
/root/work/report.txt
/root/work/README.md
/root/work/empty.txtCom - antes do modo, busca arquivos que têm todas as permissões indicadas. Só run.sh tinha permissão de execução do proprietário (u+x).
find /root/work -type f -perm -u+x/root/work/run.shCom / antes do modo, basta ter uma das permissões indicadas. 6000 é a soma de SUID (4000) e SGID (2000), e esta forma serve para checar no servidor os arquivos que, ao serem executados, rodam com as permissões do proprietário ou do grupo.
A pasta de teste não tinha nenhum, então demos SUID a run.sh e, ao executar, veio run.sh.
chmod u+s /root/work/run.shfind /root/work -type f -perm /6000/root/work/run.shMateriais antigos trazem -perm +6000 nesse lugar. Executado como está, terminou com o erro [invalid mode].
find /root/work -type f -perm +6000find: invalid mode '+6000'A forma + foi removida no findutils 4.5.12 (conforme a página man), então escreva /. O SUID dado para o teste foi retirado com chmod u-s.
-user filtra pelo nome do proprietário. Todos os arquivos de teste são de root, então -user root sozinho não filtra nada; ao juntar -name para escolher arquivos .log, veio só app.log.
find /root/work -type f -user root -name '*.log'/root/work/logs/app.log-nouser encontra arquivos cujo UID de proprietário não tem conta. Serve para checar arquivos que ficaram no servidor depois de excluir uma conta; ao trocar o proprietário de guide.txt pelo UID inexistente 1500, veio guide.txt.
chown 1500:1500 /root/work/docs/guide.txtfind /root/work -nouser/root/work/docs/guide.txt-nogroup faz a mesma checagem para o grupo, e veio guide.txt, com o grupo também trocado para 1500. Depois do teste, restauramos com chown root:root.
Com -o entre condições, basta uma delas. Ao usar com outra condição como -type f, agrupe entre parênteses as condições ligadas por -o. Coloque uma barra invertida antes dos parênteses para que o shell não os interprete primeiro, e deixe espaços entre parênteses e condições.
find /root/work -type f \( -name '*.log' -o -name '*.tmp' \)/root/work/docs/old.tmp
/root/work/logs/app.log
/root/work/logs/cache.tmp! inverte a condição logo depois dele. Ao buscar arquivos que não são .txt, vieram cinco.
find /root/work -type f ! -name '*.txt'/root/work/docs/old.tmp
/root/work/logs/app.log
/root/work/logs/cache.tmp
/root/work/README.md
/root/work/run.sh5️⃣ Usando find -exec
-exec executa o comando escrito depois para cada arquivo encontrado, com o caminho encontrado no lugar de {}. O ; no fim do comando é escrito \; para que o shell não o leia antes como separador de comandos.
find /root/work -name '*.log' -exec ls -l {} \;-rw-r--r-- 1 root root 2097152 Oct 5 14:10 /root/work/logs/app.logSe terminar com + em vez de \;, os caminhos encontrados são reunidos e o comando roda só uma vez. Comparando com echo, \; imprimiu os cinco caminhos em cinco linhas, e + em uma.
find /root/work -name '*.txt' -exec echo {} \;/root/work/docs/readme.txt
/root/work/docs/guide.txt
/root/work/report.txt
/root/work/my notes.txt
/root/work/empty.txtfind /root/work -name '*.txt' -exec echo {} +/root/work/docs/readme.txt /root/work/docs/guide.txt /root/work/report.txt /root/work/my notes.txt /root/work/empty.txtComandos que aceitam vários caminhos, como ls, são agrupados com + para reduzir as execuções. Conferimos o tamanho dos três arquivos maiores que 1k com um único ls -lh.
find /root/work -type f -size +1k -exec ls -lh {} +-rw-r--r-- 1 root root 4.9K Oct 5 14:10 /root/work/docs/guide.txt
-rw-r--r-- 1 root root 2.0M Oct 5 14:10 /root/work/logs/app.log
-rw-r--r-- 1 root root 1.2K Oct 5 14:10 /root/work/report.txt-exec também serve para ajustar em massa as permissões de uma pasta web, 644 para arquivos e 755 para pastas. Antes de executar, buscamos os arquivos com valor diferente, e vieram run.sh e my notes.txt.
find /root/work -type f ! -perm 644/root/work/run.sh
/root/work/my notes.txtArquivos e pastas têm permissões diferentes, então execute separado com -type f e -type d. chmod também aceita vários caminhos, por isso terminamos com +.
find /root/work -type f -exec chmod 644 {} +find /root/work -type d -exec chmod 755 {} +Ao buscar de novo com a mesma condição não veio nada, e a pasta backup, trocada antes para 700, também ficou com 755.
Mas run.sh também ficou com 644, e ao executar veio [Permission denied]. Em pastas com executáveis misturados, devolva a permissão de execução a esses arquivos com chmod +x.
Para mudar só arquivos dentro de subpastas, adicione -mindepth 2. Com 660 só mudaram os cinco arquivos de docs e logs, e depois de conferir voltamos para 644.
find /root/work -mindepth 2 -type f -exec chmod 660 {} +find /root/work -type f -perm 660/root/work/docs/readme.txt
/root/work/docs/guide.txt
/root/work/docs/old.tmp
/root/work/logs/app.log
/root/work/logs/cache.tmpLigando find e grep, você busca pelo conteúdo do arquivo e não pelo nome. Para simular uma checagem de web shell, criamos quatro arquivos PHP na pasta separada /root/site e colocamos o texto [base64_decode] em html-cache.php e photo.php da pasta upload.
find /root/site -type f/root/site/lib/func.php
/root/site/upload/html-cache.php
/root/site/upload/photo.php
/root/site/index.phpSe você sabe o nome do web shell, busque com -name. Ao adicionar -maxdepth 2 para descer só até a pasta upload, veio apenas html-cache.php.
find /root/site -maxdepth 2 -type f -name 'html*.php'/root/site/upload/html-cache.phpphoto.php, com nome comum, não apareceu aqui. grep -l executado por -exec imprime só os caminhos dos arquivos com o texto, e os dois apareceram.
find /root/site -name '*.php' -exec grep -l 'base64_decode' {} +/root/site/upload/html-cache.php
/root/site/upload/photo.php[base64_decode] é uma função que também aparece em arquivos do núcleo do WordPress, então abra os arquivos encontrados e confira o conteúdo antes de excluir.
-print0 coloca um caractere nulo em vez de quebra de linha entre os caminhos. O caractere nulo não aparece na tela, por isso os caminhos saíram colados em uma linha.
find /root/work -name '*.txt' -print0/root/work/docs/readme.txt/root/work/docs/guide.txt/root/work/report.txt/root/work/my notes.txt/root/work/empty.txtPara passar a outro comando nomes com espaços como my notes.txt sem quebrá-los, a saída de -print0 é usada em par com xargs -0 (conforme a página man).
6️⃣ Excluir arquivos com find e opções
Antes de excluir, execute primeiro as mesmas condições sem excluir e confira com os olhos a lista de arquivos a excluir.
find /root/work -name '*.tmp'/root/work/docs/old.tmp
/root/work/logs/cache.tmp-exec rm {} \; executa rm para cada arquivo encontrado. Executado só na pasta logs, excluiu cache.tmp e deixou apenas app.log.
find /root/work/logs -name '*.tmp' -exec rm {} \;ls /root/work/logsapp.log-delete faz o find excluir direto, sem executar rm. Ao executar não imprimiu nada, e ao buscar de novo com a mesma condição não havia mais arquivos .tmp.
find /root/work -name '*.tmp' -deletefind /root/work -name '*.tmp'-delete deve ficar sempre depois das condições. O find avalia a linha de comando do início como uma única expressão, então com -delete na frente ele tenta excluir tudo sob o caminho inicial antes de olhar as condições (conforme a página man).
🔲 Opções do comando find
📌 Principais opções: resultados deste artigo
| Opção | Tarefa | Resultado neste artigo | |
|---|---|---|---|
| -name | Encontra nomes que combinam com um padrão (diferencia maiúsculas) | '*.txt' dá cinco arquivos; 'readme*' só docs/readme.txt | |
| -iname | Compara nomes sem diferenciar maiúsculas | 'readme*' dá docs/readme.txt e README.md | |
| -type f, -type d | Deixa só arquivos comuns (f) ou pastas (d) | -type d dá quatro pastas com o caminho inicial; -type f dá dez arquivos | |
| -maxdepth | Desce só N níveis abaixo do caminho inicial | -maxdepth 1 deixa só os cinco arquivos logo abaixo de /root/work | |
| -mindepth | Pula os níveis acima de N a partir do caminho inicial | -mindepth 2 dá só os cinco arquivos dentro de subpastas | |
| -size | Busca por tamanho (+ maior, - menor, unidades c, k, M, G) | -size +1k dá três arquivos; -size -1k só empty.txt | |
| -mtime | Compara o tempo desde a modificação do conteúdo em unidades de 24 horas | -mtime -1 dá cinco arquivos; -mtime +7 dois arquivos .tmp | |
| -mmin | Compara o tempo desde a modificação em minutos | -mmin -60 dá os mesmos cinco arquivos de -mtime -1 | |
| -ctime | Compara em unidades de 24 horas até a mudança de dados do arquivo, como permissões e nome | -ctime -1 dá os dez arquivos de teste | |
| -newer | Encontra o que foi modificado depois de um arquivo de referência | Cinco arquivos com README.md, ajustado para 3 dias atrás, como referência | |
| -empty | Encontra arquivos de tamanho 0 e pastas vazias | Dá a pasta vazia backup e empty.txt | |
| -perm | Busca por permissão (só número: exatamente esse valor; - antes: todas as indicadas; / antes: pelo menos uma) | -perm 644 dá oito arquivos, -perm -u+x dá run.sh e -perm /6000 dá run.sh depois do SUID | |
| -user | Filtra pelo nome do proprietário | Com -name '*.log' dá app.log; conta inexistente termina com erro | |
| -nouser | Encontra o que tem UID de proprietário sem conta | Dá guide.txt, com o UID trocado para 1500 | |
| -nogroup | Encontra o que tem GID de grupo sem grupo | Dá guide.txt, com o GID trocado para 1500 | |
| -o | Deixa o que atende a uma das duas (entre parênteses com outras condições) | Agrupando .log e .tmp vêm três arquivos | |
| ! | Inverte a condição logo depois | Dá cinco arquivos que não são .txt | |
| -exec | Executa o comando escrito depois para cada arquivo encontrado (caminho no lugar de {}) | Terminando com +, um único echo imprime cinco caminhos em uma linha | |
| -print0 | Coloca um caractere nulo em vez de quebra de linha entre os caminhos | O caractere nulo não aparece, e os caminhos ficam colados em uma linha | |
| -delete | O find exclui direto os arquivos encontrados (fica depois das condições) | Não imprimiu nada; ao buscar de novo não havia arquivos .tmp |
📎 Outras opções: segundo o manual oficial
| Opção | Tarefa | |
|---|---|---|
| -L | Segue links simbólicos e usa os dados do arquivo de destino | |
| -path | Compara o caminho inteiro, não o nome, com um padrão do shell | |
| -regex | Compara o caminho inteiro com uma expressão regular | |
| -iregex | Compara como -regex, sem diferenciar maiúsculas | |
| -atime | Compara o tempo desde o último acesso em unidades de 24 horas | |
| -cnewer | Encontra o que mudou de estado depois da modificação do arquivo de referência | |
| -group | Filtra pelo nome do grupo proprietário | |
| -xdev | Não desce para pastas de outros sistemas de arquivos | |
| -daystart | Calcula as condições de tempo a partir das 0h de hoje em vez de 24 horas atrás | |
| -prune | Se for pasta, não desce nela | |
| -quit | Termina na hora (-print -quit imprime só o primeiro resultado) | |
| -printf | Imprime no formato que você definir | |
| -ls | Imprime os arquivos encontrados no formato ls -dils | |
| -fprint | Salva os caminhos encontrados em um arquivo indicado em vez da tela | |
| -ok | Executa como -exec, mas pergunta antes | |
| -execdir | Executa como -exec, mas roda o comando na pasta do arquivo encontrado |
🔲 Simulador do comando find
O simulador abaixo é um servidor virtual com a mesma pasta de teste, onde você pode executar condições como -name, -type, -size, -mtime e -perm, além de -exec e -delete.
7️⃣ Erros do comando find
Se você escrever um padrão sem aspas, o shell aplica as regras de Curingas e o expande primeiro nos nomes de arquivo da pasta atual. Ao ir para a pasta docs e escrever *.txt sem aspas, o shell passou os dois nomes guide.txt e readme.txt, e veio o erro abaixo.
cd /root/work/docsfind /root/work -name *.txtfind: paths must precede expression: `readme.txt'
find: possible unquoted pattern after predicate `-name'?O código de saída foi 1.
Sem \; ou + no fim de -exec, veio [missing argument to `-exec’].
find /root/work -name '*.log' -exec ls -l {}find: missing argument to `-exec'Um caminho inicial inexistente dá [No such file or directory] e termina com código de saída 1.
find /nonexistent-dir -name xfind: '/nonexistent-dir': No such file or directoryUm nome de conta inexistente em -user, ou um valor diferente das letras definidas como f e d em -type, termina na hora com erro, sem começar a busca.
find /root/work -user nosuchuserfind: 'nosuchuser' is not the name of a known userfind /root/work -type xfind: Unknown argument to -type: xCom uma conta comum no servidor Debian 12, mudamos para 000 a permissão da pasta lock dentro da pasta de teste e buscamos nessa pasta. Não foi possível ler lock, veio [Permission denied] e o código de saída foi 1.
find ~/findtest/home/user/findtest
/home/user/findtest/report.txt
/home/user/findtest/lock
find: '/home/user/findtest/lock': Permission denied
/home/user/findtest/docs
/home/user/findtest/docs/readme.txtPara esconder só as linhas de erro, adicione 2>/dev/null. O texto de erro sumiu, mas o código de saída continuou 1.
find ~/findtest -name '*.txt' 2>/dev/null/home/user/findtest/report.txt
/home/user/findtest/docs/readme.txt🔢 FAQ & conteúdo recomendado
Busca de conteúdo
Comando grep do Linux
Artigo sobre o comando grep, que encontra texto dentro de arquivos e imprime essas linhas, e suas opções.
Exclusão
Comando rm do Linux: opções do rm -rf e como apagar sem confirmação
Artigo sobre as opções -r e -f e as perguntas de confirmação do comando rm ao excluir arquivos e pastas.
Espaço em disco
Comando du: verificar o espaço em disco de arquivos
Artigo sobre como somar o espaço em disco ocupado por pastas e arquivos com o comando du.
ℹ️ Aviso de afiliados
O conteúdo deste site contém links de afiliados. Quando um visitante compra um produto ou serviço por meio de um desses links, o site recebe uma comissão do vendedor. O valor que o comprador paga (em promoções, ele diminui ↓) não aumenta por causa disso. Preços, descontos e informações de estoque valem para o momento em que o texto foi escrito e podem ter mudado, por isso confirme com o vendedor antes de comprar. Os produtos são escolhidos e avaliados por critérios próprios, e o recebimento de comissão não influencia a ordem de apresentação nem o conteúdo das avaliações.