você está aqui: Home  → Arquivo de Mensagens

find - Procurando arquivo por características

Colaboração: Julio Cezar Neves

Data de Publicação: 24 de fevereiro de 2021

O comando find é muito badalado e bastante conhecido, porém resolvi assim mesmo postar este artigo por causa de algumas características pouco conhecidas como a ação printf. Espero que vocês gostem.

Sintaxe

 find [caminho ...] expressão [ação]

O comando find procura arquivos pelo nome ou outras características.

Parâmetros

caminho Caminhos de diretório a partir do qual irá procurar pelos arquivos;
expressão Define quais critérios de pesquisa. Pode ser uma combinação entre vários tipos de procura;
ação Define que ação executar com os arquivos que atender aos critérios de pesquisa definidos por expressão.

Os principais critérios de pesquisa definidos por expressão são:

Principais critérios de pesquisa
Opção Ação
-name Procura arquivos que tenham o nome especificado. Aqui podem ser usados metacaracteres ou caracteres curingas, porém estes caracteres deverão estar entre aspas, apóstrofos ou imediatamente precedidos por uma contrabarra isso porque quem tem de expandir os coringas é o find. Se fosse o Shellque os expandisse, isto seria feito somente com relação ao diretório corrente, o que jogaria por terra a característica recursiva do find;
-user Procura arquivos que tenham usuário como dono;
-group Procura arquivos que tenham grupo como dono;
-type C Procura por arquivos que tenham o tipo Ce esses tipos estão discriminados a seguir:
b Arquivo especial acessado a bloco (esse é o padrão)
c Arquivo especial acessado a caractere
d Diretório
p Namedpipe(FIFO)
f Arquivo normal
l Linksimbólico
s Socket
-size ±N[UNID] A opção -sizeprocura por arquivos que usam N UNIDades UNID de espaço ou menos (-N) de N UNIDades UNIDde espaço. As UNID mais frequentes são descritas pelas linhas a seguir:
b Bloco de 512 bytes (valor padrão)
c Caracteres
k Kilobytes (1024 bytes)
w Palavras (2 bytes)
M Megabytes
G Gigabytes
-atime ±D Procura por arquivos que foram acessados há mais (+D) de D dias ou a menos (-D) de D dias;
-ctime ±D Procura por arquivos cujo status mudou há mais (+D) de D dias ou a menos (-D) de D dias;
-mtime ±D Procura por arquivos cujos dados foram modificados há mais (+D) de D dias ou a menos (-D) de D dias;

Exemplos

Para listar na tela (-print) todos os arquivos, a partir do diretório corrente, terminados por .sh, faça:

$ find . -name \*.sh    # Ação não especificada print é default
./undelete.sh   
./ntod.sh               # estes quatro primeiros arquivos foram
./dton.sh               # encontrados no diretório corrente.
./graph.sh
./tstsh/cotafs.sh
./tstsh/data.sh         # Estes quatro foram encontrados no
./tstsh/velha.sh        # diretório tstsh, sob o diretório corrente
./tstsh/charascii.sh

Preciso abrir espaço em um determinado file system com muita urgência, então vou remover arquivos com mais de um megabyte e cujo último acesso foi há mais de 60 dias. Para isso, vou para este file system e faço:

 $ find . type f size +1000000c atime +60 exec rm {} \;

Repare que no exemplo acima usei três critérios de pesquisa, a saber:

-type f Todos os arquivos regulares (normais)
-size +1000000c Tamanho maior do que 1000000 de caracteres (+1000000c)
-atime +60 Último acesso há mais de 60 (+60) dias.

Repare ainda que entre estes três critérios foi usado o conector e, isto é, arquivos regulares e maiores que 1MByte e sem acesso há mais de 60 dias.

Para listar todos os arquivos do disco terminados por .sh ou .txt, faria:

 $ find / -name \*.sh o name \*.txt print

Neste exemplo devemos realçar além das contrabarras (\) antes dos asteriscos (*), o uso do o para uma ou outra extensão e que o diretório inicial era o raiz (/); assim sendo, esta pesquisa deu-se no disco inteiro (o que freqüentemente é bastante demorado).

Com o printf é possível formatar a saída do comando find e especificar os dados desejados. A formatação do printf é muito semelhante à do mesmo comando na linguagem C e interpreta caracteres de formatação precedidos por um símbolo de percentual (%). Vejamos seus efeitos sobre a formatação:

Caractere Significado
%f Nome do arquivo (caminho completo não aparece)
%F Indica a qual tipo de file system o arquivo pertence
%g Grupo ao qual o arquivo pertence
%G Grupo ao qual o arquivo pertence (GID- Numérico)
%h Caminho completo do arquivo (tudo menos o nome)
%i Número do inode do arquivo (em decimal)
%m Permissão do arquivo (em octal)
%p Nome do arquivo
%s Tamanho do arquivo
%u Nome de usuário (username) do dono do arquivo
%U Número do usuário (UID) do dono do arquivo

Também é possível formatar datas e horas obedecendo às tabelas a seguir:

Caractere Significado
%a Data do último acesso
%c Data de criação
%t Data de alteração

Os três caracteres anteriores produzem uma data semelhante ao do comando date.

Veja um exemplo:

$ find . -name ".b*" -printf '%t %p\n'
Mon Nov 29 11:18:51 2020 ./.bash_logout
Tue Nov  1 09:44:16 2020 ./.bash_profile
Tue Nov  1 09:45:28 2020 ./.bashrc
Fri Dec 23 20:32:31 2020 ./.bash_history

Nesse exemplo, o %p foi o responsável por colocar os nomes dos arquivos. Caso fosse omitido, somente as datas seriam listadas.

Observe ainda que ao final foi colocado um /n. Sem ele não haveria salto de linha e a listagem anterior seria uma grande tripa.

Essas datas também podem ser formatadas, para isso basta passar as letras da tabela anterior para maiúsculas (%A, %C e %T) e usar um dos formatadores das duas tabelas a seguir:

Tabela de formatação de tempo

Caractere Significado
H Hora (00..23)
I Hora (01..12)
k Hora (0..23)
l Hora (1..12)
M Minuto (00..59)
p AM or PM
r Horário de 12 horas (hh:mm:ss) seguido de AM ou PM
S Segundos (00 ... 61)
T Horário de 24-horas (hh:mm:ss)
Z Fuso horário (na Cidade Maravilhosa BRST)

Tabela de formatação de datas

Caractere Significado
a Dia da semana abreviado (Dom...Sab)
A Dia da semana por extenso (Domingo...Sábado)
b Nome do mês abreviado (Jan...Dez)
B Dia do mês por extenso (Janeiro...Dezembro)
c Data e hora completa (Fri Dec 23 15:21:41 2020)
d Dia do mês (01...31)
D Data no formato mm/dd/aa
h Idêntico a b
j Dia seqüencial do ano (001366)
m Mês (01...12)
U Semana seqüencial do ano. Domingo como 1º dia da semana (00...53)
w Dia seqüencial da semana (0..6)
W Semana seqüencial do ano. Segunda-feira como 1º dia da semana (00...53)
x Representação da data no formato do país (definido por $LC_ALL)
y Ano com 2 dígitos (00...99)
Y Ano com 4 dígitos

Para melhorar a situação, vejamos uns exemplos; porém, vejamos primeiro quais são os arquivos do diretório corrente que começam por .b:

$ ls -la .b*
-rw-------   1 d276707  ssup  21419 Dec 26 17:35 .bash_history
-rw-r--r--   1 d276707  ssup     24 Nov 29  2020 .bash_logout
-rw-r--r--   1 d276707  ssup    194 Nov  1 09:44 .bash_profile
-rw-r--r--   1 d276707  ssup    142 Nov  1 09:45 .bashrc

Para listar esses arquivos em ordem de tamanho, podemos fazer:

$ find . -name ".b*" -printf '%s\t%p\n' | sort -n
24      ./.bash_logout
142     ./.bashrc
194     ./.bash_profile
21419   ./.bash_history

No exemplo que acabamos de ver, o \t foi substituído por um <TAB> na saída de forma a tornar a listagem mais legível. Para listar os mesmos arquivos classificados por data e hora da última alteração:

$ find . -name ".b*" -printf '%TY-%Tm-%Td %TH:%TM:%TS %p\n' | sort
2020-11-29 11:18:51 ./.bash_logout
2020-11-01 09:44:16 ./.bash_profile
2020-11-01 09:45:28 ./.bashrc
2020-12-26 17:35:13 ./.bash_history

Espero que o texto tenha sido útil.



Veja a relação completa dos artigos de Julio Cezar Neves