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 acessadon
minutos atrás;-atime n
: O arquivo foi acessado nos últimosn
dias (n
é multiplicado por 24 horas automaticamente);-ctime n
: O arquivo foi modificado nos últimosn
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 grupogname
;-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 contenhapattern
;-perm mode
: As permissões do arquivo (em octal) correspondem aperm
;-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 regularpattern
;-size n[UNIDADE]
: O arquivo ocupan
unidades de armazenamento. As unidades incluemk
para kilobyte,M
para megabyte eG
para gigabyte;-type c
: Arquivo é do tipoc
. Dentre os tipos válidos estãof
para arquivo,d
para diretório el
para link simbólico;-uid n
: Arquivo cujo dono tem IDn
;-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 {} \; < ls ... ./a > ? y -rw-r--r-- 1 beraldo beraldo 0 Jan 17 14:41 ./a < ls ... ./b > ? y -rw-r--r-- 1 beraldo beraldo 0 Jan 17 14:41 ./b < ls ... ./c > ? 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.
Roberto Beraldo
Latest posts by Roberto Beraldo (see all)
- Não Tenha Preguiça de Ler! - 25/04/2016
- Como Atualizar Scripts PHP de MySQL Para MySQLi - 29/10/2015
- Como usar PDO com banco de dados MySQL - 10/09/2015