Encontrando arquivos com o find

O comando find é um aplicativo para linha de comando para busca de arquivos utilizado em sistemas operativos Unix-like e derivados. Com o find é possível localizar arquivos e diretórios baseados em um critério de busca. Ele também suporta expressões regulares, e pode ser usado para aplicar um filtro especifico em vários arquivos.

EXEMPLOS:
[root@celta tadeu]# find . 
.
./.bash_profile
./.bashrc
./teste1
./.config
./.config/abrt
./.bash_history
./.bash_logout
./backup_etc.tar.gz
./.cache
./.cache/abrt
./.cache/abrt/lastnotification
./.ssh
./.ssh/authorized_keys

Este comando irá buscar todo o conteúdo do diretório corrente, funciona praticamente como um ls.

[root@celta tadeu]# find -iname teste1 
./teste1

Este exemplo busca no diretório corrente o arquivo de nome “teste1”. Para buscar por um arquivo em outros diretórios precisamos passar o path para o find, exemplo:

[root@celta tadeu]# find / -iname hosts 
/etc/hosts

Podemos usar também os caracteres especiais com o find para fazermos buscas mais precisas, por exemplo:

[root@celta tadeu]# find -iname '*.tar.gz' 
./backup_etc.tar.gz

Este comando irá buscar todo o diretório / arquivos que terminem com tar.gz:

[root@celta tadeu]# find / -iname '*.tar.gz' 
/root/backup_files_bacula.tar.gz
/root/backup/Backup_etc-15_02_17-14:52.tar.gz
/root/backup/Backup_etc-15_02_17-14:53.tar.gz
/root/backup/Backup_etc-20_02_17-10:11.tar.gz
/home/tadeu/backup_etc.tar.gz
/etc/Backup-etc-14_02_17-00:16.tar.gz

Neste exemplo buscamos todos os arquivos que termine com tar.gz a partir da raiz, já que passamos o path (“/”) para o find. Podemos utilizar também a diretiva type para determinarmos que tipo de arquivo desejamos buscar:

[root@celta /]# find /var/log/ -maxdepth 1 -type d 
/var/log/
/var/log/ppp
/var/log/sa
/var/log/audit
/var/log/tuned
/var/log/chrony
/var/log/anaconda
/var/log/ntpstats
/var/log/bacula
/var/log/mariadb

Nesse exemplo podemos verificar a quantidade de diretórios existentes dentro do /var/log.
A diretiva maxdepth limita os níveis de busca do find, e se quisermos tirar a prova real:

[root@celta /]# cd /var/log

[root@celta log]# ls -lthr | grep ^d  | wc -l 
9

Com o find é possível fazer algumas combinações interessantes utilizando a diretiva type e name:

[root@celta ~]#  find /etc/ -type f -name '*.conf' 
/etc/abrt/abrt-action-save-package-data.conf
/etc/abrt/abrt.conf
/etc/abrt/gpg_keys.conf
/etc/abrt/plugins/xorg.conf
/etc/abrt/plugins/oops.conf
...
...
...
...

Neste exemplo buscamos no /etc/ pelos arquivos “.conf”. E se quisermos negar a busca utilizamos um (“**\!**) antes do -name:

[root@celta ~]#  find /etc/ -type f \! -name '*.conf' | head -n5 
/etc/Backup-etc-14_02_17-00:16.tar.gz
/etc/adjtime
/etc/aliases
/etc/aliases.db
/etc/anacrontab
...
...
...

Podemos também limitar a busca ao diretório /etc/ utilizando a diretiva maxdepth:

[root@celta /]# find / -maxdepth 2 -type f -name '*.conf'
/etc/asound.conf
/etc/chrony.conf
/etc/dnsmasq.conf
/etc/dracut.conf
/etc/e2fsck.conf
...
...
...

Com o find também podemos buscar arquivos pelo tamanho utilizando a diretiva size:

[root@celta tadeu]# find /home/tadeu -type f -size +2M
/home/tadeu/teste1
/home/tadeu/backup_etc.tar.gz

Neste exemplo estamos buscando arquivos com mais de 2M. Uma combinação legal para o find com o size é utilizar o comando xargs passando o comando du como argumento, exemplo:

[root@celta tadeu]# find /home/tadeu -type f -size +2M | xargs -I{} du -h '{}' 
20M	/home/tadeu/teste1
36M	/home/tadeu/backup_etc.tar.gz

Para buscarmos por um arquivo com o tamanho identico a 2M, por exemplo, utilizamos o -size 2M.

[root@celta tadeu]# find /home/tadeu -type f -size 2M | xargs -I{} du -h '{}' 
2,0M	/home/tadeu/file_2M

Obs: Para criar um arquivo de tamanho igual a 2M utilizamos o utilitário fallocate. Ex:

[root@celta tadeu]# fallocate -l 2000048 file_2M

Para arquivos com menos de 2M, utilizamos:

[root@celta tadeu]# find /home/tadeu  -type f -size -2M | xargs -I{} du -h '{}' 
4,0K	/home/tadeu/.bash_profile
4,0K	/home/tadeu/.bashrc
4,0K	/home/tadeu/.bash_history
4,0K	/home/tadeu/.bash_logout
4,0K	/home/tadeu/.cache/abrt/lastnotification
4,0K	/home/tadeu/.ssh/authorized_keys

Com o find também podemos buscar arquivos a partir da dono, ex:

[root@celta /]# find / -type f -user tadeu -exec ls -la '{}' \; 2> /dev/null | head -n5 
-rw-rw----. 1 tadeu mail 0 Dez 10 12:20 /var/spool/mail/tadeu
-rw-r--r--. 1 tadeu tadeu 193 Nov 20  2015 /home/tadeu/.bash_profile
-rw-r--r--. 1 tadeu tadeu 231 Nov 20  2015 /home/tadeu/.bashrc
-rw-r--r--. 1 tadeu tadeu 20000048 Dez 10 12:53 /home/tadeu/teste1
-rw-------. 1 tadeu tadeu 333 Dez 17 13:11 /home/tadeu/.bash_history

Outro critério útil para a busca com o find é o de permissão (**-perm**):

[root@celta ~]# find /home/tadeu -type f -perm 644 -exec ls -la '{}' \; 
-rw-r--r--. 1 tadeu tadeu 193 Nov 20  2015 /home/tadeu/.bash_profile
-rw-r--r--. 1 tadeu tadeu 231 Nov 20  2015 /home/tadeu/.bashrc
-rw-r--r-- 1 root root 2000048 Fev 20 15:11 /home/tadeu/file_2M
-rw-r--r--. 1 tadeu tadeu 20000048 Dez 10 12:53 /home/tadeu/teste1
-rw-r--r--. 1 tadeu tadeu 18 Nov 20  2015 /home/tadeu/.bash_logout
-rw-r--r-- 1 root root 37673010 Fev 15 14:42 /home/tadeu/backup_etc.tar.gz
OUTROS CRITÉRIOS COMUNS:
-atime -/+n Arquivo acessado, antes ou após n, n corresponde à expressão n * 24 horas.
-ctime -/+n Arquivo criado antes ou após n.
-mtime -/+n Arquivo modificado antes ou após n.
-amin -/+n Arquivo acessado, antes ou após n, n corresponde à quantiade de minutos.
-cmin -/+n Arquivo criado antes ou depois de n.
-mmin -/+n Arquivo modificado antes ou depois de n.

EXEMPLOS UTÉIS COMBINADOS:

Com o find podemos combinar com o cpio e o xargs criando cópias dos arquivos e sua estrutura, bastante útil para criação de scripts de backups.
Exemplo:

– Compactar o /etc com o compressor gzip;
– Este arquivo deverá ficar no diretório /root/backup;
– O nome do arquivo deverá possuir a data e horário do backup:

[root@celta /]# cd /root/backup/

[root@celta backup]# find /etc/ | cpio -pmvd /root/backup/ | xargs tar -czv --force-local -f Backup_etc-`date +%d_%m_%y-%H:%M`.tar.gz /etc && rm -rf etc/ 

Outro exemplo:

– Compactar todos os arquivos .conf do /etc com o compressor gzip;
– Este arquivo deverá ficar no diretório /root;
– No final deverá listar os arquivos compactados;:

[root@celta /]# cd /root/

[root@celta ~]# find /etc/ -maxdepth 1 -type f -name '*.conf' -exec cp -pr '{}' /root/ \; &&  tar -czvf backup_conf_etc.tar.gz *.conf > /dev/null && rm -rf *.conf && tar -tzvf backup_conf_etc.tar.gz

Uma forma mais fácil e simplificada do último exemplo:

[root@celta ~]# find /etc/ -maxdepth 1 -type f -name '*.conf' | tar -czvf conf.tar.gz -T -

Porém nesse caso ele copia o /etc/ também. Outro exemplo:

[root@celta /]# cd /root/

[root@celta ~]# find /etc/ -maxdepth 1 -type f -name '*.conf' -exec cp -pr '{}' /root \; && tar -czvf backup_conf_etc.tar.gz *.conf && rm -rf *.conf

Referência:
https://linux.die.net/man/1/find