Linux / Comando find: buscar arquivos por nome, tamanho e data

O comando find procura arquivos e diretórios percorrendo os caminhos que você indicar. Ele combina condições de nome, tipo, tamanho e data de modificação, e pode mostrar os resultados ou executar uma ação sobre eles. A pesquisa usa o sistema de arquivos atual, sem depender de um índice previamente atualizado.

Os exemplos seguem o GNU Findutils e usam Bash e utilitários GNU como mktemp, realpath, truncate e touch. A preparação cria uma pasta exclusiva com arquivos pequenos e tamanhos lógicos de aproximadamente 1 MiB. A única exclusão proposta fica limitada a um arquivo descartável dessa pasta e exige uma decisão após a prévia; não aplique o bloco de prática a diretórios de produção.

Como o find combina caminhos, testes e ações

Primeiro vêm os caminhos iniciais; depois, a expressão de busca. Testes consecutivos normalmente são ligados por um E lógico implícito: -type f -name '*.log' exige um arquivo regular e um nome correspondente. Ao usar apenas testes, o resultado recebe a ação padrão -print. Ações como -exec e -delete substituem essa impressão implícita. A avaliação respeita a precedência dos operadores e pode parar assim que o resultado lógico estiver decidido; não é uma simples lista de filtros independentes.

Sintaxe básica

find [opções de links] [caminho-inicial]... [expressão]

caminho-inicial e expressão são marcadores. No GNU find, sem caminho explícito a busca começa em ., a pasta atual; prefira informar o caminho para tornar o escopo claro. -P, -H e -L, quando usados, ficam antes dos caminhos. Confira find --version, find --help e man find no destino: outras implementações podem não aceitar todas as extensões GNU.

Uso básico do find

Preparar arquivos e pesquisar por nome

Execute o bloco no mesmo terminal e pare se houver erro. Ele prepara logs em dois níveis, nomes com letras maiúsculas e espaços, dois arquivos com pouco mais ou exatamente 1 MiB e um cache de prática. As datas de alguns arquivos são ajustadas apenas para demonstrar os filtros. A última busca mostra três caminhos, em ordem: ./logs/app.log, ./logs/older.log e ./logs/sub/nested.log. O diretório name.log não entra porque o teste exige -type f; server.LOG não corresponde ao padrão sensível a maiúsculas.

find_start=$PWD
find_demo=$(mktemp -d -p "$PWD" 'find-demo.XXXXXXXX') &&
find_demo=$(realpath -e -- "$find_demo") &&
cd -- "$find_demo" &&
mkdir -p -- logs/sub empty-dir name.log cache &&
printf 'app\n' > logs/app.log &&
printf 'server\n' > logs/server.LOG &&
printf 'nested\n' > logs/sub/nested.log &&
printf 'temporario\n' > 'logs/file space.tmp' &&
printf 'temporario\n' > logs/-leading.tmp &&
printf 'expirado\n' > cache/expired.tmp &&
printf 'limite\n' > cache/border.tmp &&
printf 'recente\n' > cache/recent.tmp &&
printf 'preservar\n' > cache/keep.txt &&
printf 'controle intacto\n' > sentinel.txt &&
touch -- zero.bin &&
truncate -s 1M -- exactly.bin &&
truncate -s 1048577 -- over.bin &&
touch -d '2 hours ago' -- logs/older.log &&
touch -d '40 days ago' -- cache/expired.tmp &&
touch -d '732 hours ago' -- cache/border.tmp &&
find . -type f -name '*.log' -print | LC_ALL=C sort

Filtrar por tipo e tamanho

O exemplo usa -size +1M para manter a prática pequena e seleciona somente ./over.bin, com 1.048.577 bytes. M significa MiB: 1.048.576 bytes. Pelo mesmo critério, -size +100M selecionaria arquivos maiores que 100 MiB. Segundo a documentação de tamanho, o valor é arredondado para cima na unidade escolhida: -size 1M pode corresponder a qualquer arquivo de 1 a 1.048.576 bytes, e -size -1M só a arquivos de zero byte. Para tamanho exato em bytes, use -size 1048576c. Trata-se do tamanho lógico, não necessariamente do espaço físico reservado no disco.

cd -- "$find_demo" &&
find . -type f -size +1M -print

Filtrar por tempo de modificação

Logo após a preparação, o exemplo mostra app.log e sub/nested.log; older.log foi ajustado para duas horas atrás, fora da janela -mmin -60, e server.LOG não passa pelo padrão de nome. -mtime conta períodos de 24 horas com a parte fracionária descartada: -mtime 0 cobre menos de 24 horas e -mtime 1, de 24 até menos de 48 horas. Assim, -mtime +30 exige pelo menos 31 períodos completos, não apenas um pouco mais de 30 dias. A documentação de intervalos de idade explica também a granularidade em minutos. As janelas são relativas ao início da busca; com o passar do tempo, os resultados mudam.

cd -- "$find_demo" &&
find ./logs -type f -name '*.log' -mmin -60 -print | LC_ALL=C sort

Conferir o escopo e os caminhos retornados

Dentro da pasta exclusiva, crie um subdiretório e um arquivo de texto. O resultado inclui o caminho inicial informado: começar em demo-find produz demo-find/a.txt, enquanto começar em . pode produzir um caminho iniciado por ./, e um caminho inicial absoluto produz caminhos absolutos. find não ordena os resultados automaticamente; as práticas usam sort somente quando uma ordem fixa facilita a conferência.

cd -- "$find_demo" &&
mkdir -- demo-find &&
touch -- demo-find/a.txt &&
find demo-find -name '*.txt' -print

Saída esperada deste bloco:

demo-find/a.txt

O ponto inicial também é avaliado. -maxdepth 0 testa apenas esse ponto; -maxdepth 1 inclui seus filhos imediatos, e -mindepth 1 evita aplicar ações ao próprio ponto inicial. Essas opções não são equivalentes a procurar apenas arquivos regulares. Antes de executar ações, confira os caminhos e a expressão completos.

Principais opções

Opção Efeito no GNU find
-name PADRÃO Comparar apenas o nome final, com distinção de maiúsculas. O padrão é de shell, não uma expressão regular.
-iname PADRÃO Comparar o nome sem distinguir maiúsculas, conforme as regras de caracteres do ambiente.
-type TIPO Selecionar f para arquivo regular, d para diretório ou l para link simbólico, considerando a política de links.
-maxdepth N Limitar a profundidade; o ponto inicial tem profundidade zero.
-mtime N Comparar períodos completos de 24 horas desde a modificação. +N e -N selecionam intervalos.
-size N Comparar tamanho lógico, arredondado para cima na unidade; c conta bytes, M conta MiB.
-exec COMANDO {} + Acumular caminhos como argumentos separados, em um ou mais lotes. Não exige interpretar os nomes como texto de shell.
-delete Excluir imediatamente quando a avaliação alcançar a ação; ativa -depth e pode remover diretórios vazios.

Exemplos práticos

Encontrar diretórios vazios

O bloco retorna ./empty-dir e ./name.log. -empty também corresponde a arquivos regulares de zero byte; o teste -type d impede que zero.bin seja listado nesta busca. Listar um diretório vazio não o remove, e o resultado pode mudar se outro processo criar conteúdo durante a pesquisa.

cd -- "$find_demo" &&
find . -type d -empty -print | LC_ALL=C sort

Passar arquivos correspondentes como argumentos

Este exemplo apenas lista, com ls -ld --, os dois arquivos .tmp dentro de logs: -leading.tmp e file space.tmp. '{}' + passa cada caminho como um argumento inteiro; espaços e quebras de linha não viram separadores de argumentos. A posição de {} deve ser a última antes de + nessa forma, e o find pode executar mais de um lote se houver muitos caminhos. A data e as permissões mostradas por ls dependem do ambiente; não use esse texto formatado como uma lista para outro programa. O manual de find detalha as diferenças entre -exec e -execdir e os estados de saída.

cd -- "$find_demo" &&
find ./logs -type f -name '*.tmp' -exec ls -ld -- '{}' +

Revisar antes de excluir no cache de prática

Execute somente após a preparação e mantenha a pasta sem alterações concorrentes. O bloco resolve o caminho absoluto de cache e confere que ele é exatamente o cache da pasta exclusiva, recusando um link simbólico nesse ponto. A prévia deve mostrar apenas o caminho terminado em /cache/expired.tmp, ajustado para 40 dias atrás. border.tmp tem cerca de 30 dias e meio e não satisfaz -mtime +30; recent.tmp e keep.txt também devem permanecer. Só digite APAGAR se a lista for essa; qualquer outra resposta mantém os arquivos. Ambas as buscas usam -depth e os mesmos testes. O find executa a ação de exclusão na segunda busca; a impressão posterior ocorre apenas para exclusões bem-sucedidas.

if [[ -n "$find_demo" && -d "$find_demo/cache" && ! -L "$find_demo/cache" ]] &&
   cache_root=$(realpath -e -- "$find_demo/cache") &&
   [[ "$cache_root" == "$find_demo/cache" ]]; then
  find -P "$cache_root" -depth -type f -name '*.tmp' -mtime +30 -print &&
  read -r -p 'Confira a lista. Digite APAGAR para excluir: ' resposta &&
  if [[ "$resposta" == APAGAR ]]; then
    find -P "$cache_root" -depth -type f -name '*.tmp' -mtime +30 -delete -print
  else
    printf 'Arquivos preservados.\n'
  fi
else
  printf 'Cache de pratica invalido; nenhuma exclusao.\n' >&2
fi

Depois de uma exclusão bem-sucedida, apenas expired.tmp deve desaparecer; repetir a mesma busca não deve encontrar esse arquivo. Não há lixeira nem restauração automática pelo find. A documentação de -delete recomenda incluir -depth também na prévia, pois a exclusão o ativa implicitamente. -prune perde seu efeito com -depth; não combine os dois esperando proteger uma subárvore. Uma prévia não bloqueia mudanças no sistema de arquivos: este exercício não é um mecanismo de limpeza para pastas alteradas por outros usuários.

Comparar find e outros comandos

Comando Função principal Quando usar
find Percorrer caminhos e testar metadados Procurar por nome, tipo, tamanho ou data atuais
locate Consultar um índice de nomes Localizar nomes rapidamente quando o índice for adequado e atualizado
which Procurar executáveis externos no PATH Consultar caminhos de programas; para a resolução do shell, conferir também command -v ou type
grep -R Pesquisar texto no conteúdo Encontrar palavras ou padrões dentro dos arquivos

Cuidados importantes

Proteger padrões e nomes de arquivos

Coloque '*.log' entre aspas para que o shell entregue o padrão ao find, em vez de expandi-lo antes. -name examina o nome final; para padrões de caminho inteiro, o GNU find oferece -path. Prefira caminhos iniciais explícitos como ./logs ou caminhos absolutos. Para processar resultados, use -exec com argumentos ou -print0 com um consumidor de itens separados por NUL; não divida a saída comum com substituição de comando ou por espaços. Preservar os argumentos evita quebras de nomes, mas não elimina disputas de acesso a caminhos que outros processos podem trocar.

Controlar links, montagens e erros

No GNU find, o padrão -P examina links simbólicos sem seguir seus destinos; -H segue os links fornecidos como pontos iniciais e -L tenta seguir os links durante a busca. Isso pode mudar tanto a área visitada quanto o resultado de -type; veja a documentação de links simbólicos. -xdev evita descer para diretórios em outros sistemas de arquivos, mas não é um limite geral de segurança. Erros de permissão podem deixar a lista parcial e produzir um estado não zero. Leia o erro e ajuste o ponto inicial ou a permissão necessária; não trate uma lista parcial como uma varredura completa nem acrescente privilégios automaticamente.

Agrupar expressões com OU

O E implícito tem precedência maior que -o (OU). Para exigir arquivo regular e aceitar .log ou .txt, use find . -type f \( -name '*.log' -o -name '*.txt' \) -print. As barras protegem os parênteses do shell. Sem agrupamento, o teste de tipo pode se aplicar a apenas um lado do OU; além disso, uma ação -print colocada só no fim pode deixar de executar quando o lado anterior já for verdadeiro. Coloque ações depois dos testes que devem controlá-las. A documentação dos operadores explica essa avaliação com curto-circuito. Ao terminar as práticas, volte com cd -- "$find_start".

Perguntas frequentes

O find pesquisa subdiretórios automaticamente?

Sim, a partir dos caminhos iniciais, dentro das regras de acesso e da política de links. -maxdepth limita a profundidade; -maxdepth 1 inclui o ponto inicial e seus filhos imediatos, e -maxdepth 0 testa apenas o próprio ponto inicial.

Como ignorar maiúsculas e minúsculas no nome?

No GNU find, use -iname '*.log'. Na pasta preparada, essa forma inclui server.LOG além dos nomes terminados em .log. Mantenha as aspas para proteger o padrão da expansão pelo shell.

Como tratar nomes com espaços sem separá-los?

Passe os caminhos como argumentos com -exec COMANDO '{}' + ou use -print0 com uma ferramenta compatível com NUL. O próprio comando chamado deve tratar os nomes como operandos; quando ele aceitar, use -- antes deles. Não analise a saída visual de ls para reconstruir nomes.

Qual é a diferença entre find e locate?

find percorre a árvore atual e pode testar metadados. locate consulta um banco de dados de nomes, o que costuma reduzir o trabalho de busca, mas sua lista depende da atualização e das regras do índice. Um arquivo recém-criado ou removido pode ainda não estar refletido no banco; não há uma garantia universal de velocidade.