find: como encontrar arquivos no Linux

find: como encontrar arquivos no Linux

Buscar arquivos tem ficado cada vez mais fácil usando interface gráfica. Porém, há momentos em que os filtros oferecidos pelas interfaces não são suficientes. Além disso, caso você esteja gerenciando um servidor Linux via SSH, não terá interface gráfica e terá de usar o (muito) bom e velho comando find.

O comando find permite buscar arquivos filtrando por nome, tamanho, data, dono, grupo, permissões, tipo e outros. A busca é recursiva, por padrão, mas pode ser restringida a uma determinada profundidade. Em suma, o find é uma ferramenta bem completa e poderosa.

Nota: Este artigo é um a versão reduzida do artigo bônus do curso Shell Script Para Programadores. Para conhecer melhor o curso e fazer sua matrícula, clique aqui.

 

Uma nota importante. Vou falar muito em arquivos. Vale lembrar que, no Linux e em outros sistemas Unix-Like (como o Mac OS X), diretórios e links simbólicos também são tratados como arquivos. Logo, quando eu citar arquivo, isso também vai incluir diretórios e links.

Sintaxe do comando find

A sintaxe do comando find é a seguinte:

find local_da_busca criterios_da_busca acoes

Os arquivos encontrados são exibidos na saída padrão. Se nenhum arquivo for encontrado, nada é exibido.

Antes de mostrar exemplos práticos de uso, é importante listar as opções mais comuns do find.

Opções do comando find

Assim como diversas outras ferramentas e comandos do Linux, o possui inúmeras opções e parâmetros. Vou mostrar aqui as mais frequentemente utilizadas e conhecidas.

  • -maxdepth NUM: altera o nível da profundidade da busca;
  • -regextype TYPE: altera o tipo de expressão regular utilizada pelas opções -regex e -iregex;
  • -amin n: o arquivo foi acessado n minutos atrás;
  • -atime n: O arquivo foi acessado nos últimos n dias (n é multiplicado por 24 horas automaticamente);
  • -ctime n: O arquivo foi modificado nos últimos n dias (n é multiplicado por 24 horas automaticamente);
  • -empty: Arquivo ou diretório está vazio;
  • -gid n: Arquivo cujo número do grupo do dono é n;
  • -group gname: Arquivo pertence ao grupo gname;
  • -iname pattern: Igual a -name, porém é case-insensitive (não diferencia maiúsculas e minúsculas);
  • -iregex pattern: Igual a -regex, porém é case-insensitive (não diferencia maiúsculas e minúsculas);
  • -name pattern: Arquivos cujo nome contenha pattern;
  • -perm mode: As permissões do arquivo (em octal) correspondem a perm;
  • -perm -mode: As permissões do arquivo estão no padrão definido por -mode. É possível filtrar por -perm -g=w, por exemplo. Uma forma mais genérica e menos restrita que usar -perm perm;
  • -regex pattern: Nome do arquivo coincide com a expressão regular pattern;
  • -size n[UNIDADE]: O arquivo ocupa n unidades de armazenamento. As unidades incluem k para kilobyte, M para megabyte e G para gigabyte;
  • -type c: Arquivo é do tipo c. Dentre os tipos válidos estão f para arquivo, d para diretório e l para link simbólico;
  • -uid n: Arquivo cujo dono tem ID n;
  • -user username: Arquivo cujo dono é username;
  • Ações

Além de filtrar por nome, tipo, dono etc, é possível realizar ações com os arquivos encontrados. As principais são:

  • -delete: Remove o arquivo encontrado;
  • -exec command ;: executa uma ação (comando) com o arquivo;
  • -ok command ;: Semelhante a -exec command ;, mas pede permissão ao usuário antes de executar o comando;

Exemplos de Uso do Comando find

Agora que já vimos as principais opções e parâmetros, vamos a exemplos práticos.

O exemplo mais básico

O exemplo mais simples é o seguinte:

$ find .

Esse comendo lista todos os arquivos, de forma recursiva, a partir do diretório atual (.).

Filtrando por nome de arquivo, usando string

Para filtrar por nome de arquivo, usamos a opção -name. Para ignorar diferenças entre maiúsculas e minúsculas, usamos -iname.

$ find / -name "hosts"

Esse comando procura por arquivos com o nome “hosts” em todo o sistema de arquivos (/). Se você executar como usuário normal (sem ser root), verá vários erros como estes:

find: `/root': Permission denied
find: `/etc/ssl/private': Permission denied

Essas mensagens são enviadas para a saída de erro. Logo, podemos eliminá-las, redirecionando a saída de erros para /dev/null, desta forma:

$ find / -name "hosts" 2> /dev/null

Para realizar buscas case-insensitive, basta usar -iname, desta forma:

$ find / -iname "hosts" 2> /dev/null

Filtrando por extensão de arquivo

Também usaremos -name (ou -iname) para isso. Basta usar o asterisco, desta forma:

$ find / -name '*.conf'

Pordemos fazer um OR (OU) no comando find, usando a opção -o. Isso é válido para diversos outros parâmetros, não apenas o -name, desta forma:

$ find / -name '*.ini' -o -name '*.conf'

Filtrando por nome de arquivo, usando Expressões Regulares

É possível usar Expressões Regulares (ERs) para a filtragem. Se você não conhece Expressões Regulares, é bom agilizar e começar a ler o Expressões Regulares – Guia de Consulta Rápida, do Aurelio Marinho Jargas, disponibilizado online e gratuitamente pelo próprio autor.

A filtragem por ERs, ao contrário da filtragem por string, é feita em todo o caminho (path) do arquivo. Ou seja, se quiser encontrar o arquivo ./fubar3, você pode usar as ERs .*bar.' ou .*b.*3, porém não poderá usar f.*r3, pois ela não coincidirá com o padrão ./ no início do path.

Por exemplo, o seguinte comando não retornará saída alguma:

$ find / -regex "hosts" 2> /dev/null

Já o seguinte comando retornará resultados:

$ find / -regex ".*hosts" 2> /dev/null
/etc/hosts
/etc/avahi/hosts
/etc/exim4/conf.d/router/150_exim4-config_hubbed_hosts
/home/beraldo/.ssh/known_hosts

Alterando o Tipo das Expressões Regulares

O comando find suporta diversos tipos de Expressões Regulares (ERs). São eles: emacs (que é o tipo padrão), posix-awk, posix-basic, posix-egrep e posix-extended.

Para alterar o tipo das ERs, usamos a opção -regextype TIPO.

O tipo padrão (emacs) não suporta alguns recursos, como quantificadires. Para mostrar isso na prática, criei um arquivo chamado aaarquivo (com 3 letras “a”) no diretório atual. Vamos testar os seguintes comandos:

$ find . -regex ".*a{3}rquivo"

O comando acima não retorna resultados, pois os quantificadores não são interpretados. Porém, se mudarmos o tipo das ERs para posix-egrep, o resultado será exibido, conforme o comando abaixo.

$ find . -regextype posix-egrep -regex ".*a{3}rquivo"
./aaarquivo

Para mais detalhes sobre ERs e o padrão posix-egrep veja o meu post grep: como buscar em arquivos no Linux.

Filtrando por tipo de arquivo

É possível filtrar por tipo de arquivo (arquivo, diretório, link simbólico etc), usando a opção -type.

Filtrando apenas por arquivos

Para filtrar apenas por arquivos, usamos o opção -type f:

$ find /usr/bin -type f

Filtrando apenas por diretórios

Para filtrar apenas por diretórios, usamos o opção -type d:

$ find /usr -type d

Filtrando apenas por links simbólicos

Para filtrar apenas por links simbólicos, usamos o opção -type l:

$ find /usr/bin -type l

Há outros tipos disponíveis, porém pouco utilizados. Veja o manual (man find) para ver todas as possibilidades.

[cta id=’925′]

Filtrando por data

Para filtrar por data de modificação, usamos a opção -mtime. Vamos a alguns exemplos.

# arquivos modificados entre agora e 1 dia atrás (últimas 24 horas)
$ find . -mtime 0
 
# arquivos modificados a menos de um dia (últimas 24 horas, igual ao comando anterior)
$ find . -mtime -1 
 
# arquivos modificados entre 24 e 48 horas atrás
$ find . -mtime 1
 
# arquivos modificados há mais de 48 horas
$ find . -mtime +1
 
# Arquivos modificados entre 6 e 9 monutos atrás
$ find . -mmin +5 -mmin -10

A mesma lógica é usada nos outros parâmetros de busca por data, como -atime.

Filtrando por nome de usuário

$ find /home/ -user beraldo

Filtranso por grupo

$ find / -group nome_do_grupo

Filtranso por tamanho de arquivo

O comando a seguir busca por arquivos com mais de 2 MB.

$ find . -size +2M

Este comando buscar por arquivos com, exatamente, 2MB:

$ find . -size 2M

Por fim, este busca por arquivos com menos de 2MB:

$ find . -size -2M

O comando a seguir lista arquivos maiores que 50MB e menores que 100MB.

$ find / -size +50M -size -100M

Filtrando por permissão

Filtrando por arquivos com permissão 644:

$ find . -perm 664

Este comando filtra por arquivos com permissão, no mínimo, 644. Ou seja, arquivos com mais permissões também serão exibidos (incluindo arquivos com permissão 777, por exemplo):

$ find . -perm -664

O comando a seguir filtra por arquivos que tenham permissão de escrita (número 2, em octal) para algum usuário (o próprio dono, o grupo ou outros usuários):

$ find . -perm /222

Os 3 comandos a seguir se comportam da mesma forma. São listados arquivos que possuam permissão de escrita pelo dono ou pelo grupo (OU não exclusivo).

$ find . -perm /220 
$ find . -perm /u+w,g+w 
$ find . -perm /u=w,g=w

Estes 2 comandos abaixo se comportam da mesma forma. Eles listam arquivos que possuam permissão de escrita pelo dono e pelo grupo:

$ find . -perm -220 
$ find . -perm -g+w,u+w

Os 2 comandos abaixo também se comportam da mesma forma. Ele lista arquivos que possam ser lidos por todos (-perm -444 ou -perm -a+r), possuem ao menos um bit de escrita, podendo ser escrito pelo dono, grupo ou outros (-perm /222 ou -perm /a+w), porém não pode ser executado por ninguém (! -perm /111 ou ! -perm /a+x).

$ find . -perm -444 -perm /222 ! -perm /111 
$ find . -perm -a+r -perm /a+w ! -perm /a+x

Para mais detalhes sobre permissões, veja o meu post CHMOD: Permissões em Sistemas Linux e Unix-Like.

Executando Ações Com os Arquivos Encontrados pelo find

É possível executar ações com os arquivos encontrados pelo comando find.

A sintaxe é a seguinte:

$ find diretorio opcoes -exec comando {} \;

Os caracteres {} serão trocados automaticamente pelo arquivo encontrado.

Por exemplo, para executarmos ls -ldh <arquivo> para cada arquivo encontrado no diretório atual, fazemos o seguinte:

$ find . -maxdepth 1 -type f -exec ls -lhd {} \;

Além do -exec, existe o -ok, que se comporta da mesma forma, porém, antes de executar o comando, pergunta ao usuário. É útil para prevenir a execução de comandos errados. Imagine que você executa um rm no arquivo errado…

$ find . -maxdepth 1 -type f -ok ls -lhd {} \;
&lt; ls ... ./a &gt; ? y
-rw-r--r-- 1 beraldo beraldo 0 Jan 17 14:41 ./a
&lt; ls ... ./b &gt; ? y
-rw-r--r-- 1 beraldo beraldo 0 Jan 17 14:41 ./b
&lt; ls ... ./c &gt; ? y
-rw-r--r-- 1 beraldo beraldo 0 Jan 17 14:41 ./c

Para confirmar a execução, digite y (de yes).

Removendo arquivos encontrados

Em vez de usar o comando rm no -exec, é possível usar diretamente a opção -delete, que remove os arquivos encontrados. Por exemplo:

$ find . -maxdepth 1 -type f -delete

Porém as remoções serão feitas sem a confirmação do usuário. Se desejar que seja perguntado, use -ok, como mostrado anteriormente.

Conclusão

O comando find faz buscas bem mais detalhadas que as buscas feitas pela interface gráfica. É um ferramenta muito versátil e poderosa.

Há diversas outras opções e parâmetros, além dos que mostrei aqui. Veja o manual (man find) para mais detalhes. Mostrei aqui apenas os mais utilizados no dia-a-dia.

Para aprender mais sobre Comandos Linux e Shell Script, veja meu curso Shell Script Para Programadores.

The following two tabs change content below.
Graduado em Ciência da Computação, pela Universidade Federal do Paraná (UFPR), é desenvolvedor de software desde 2008, com foco em Desenvolvimento Web com PHP.