você está aqui: Home → Colunistas → Cantinho do Shell
Por Julio Cezar Neves
O comando find é muito badalado e bastante conhecido, porém resolvi assim mesmo postar este artigo no nosso Cantinho do Shell por causa de algumas características pouco conhecidas como a ação printf. Espero que vocês gostem.
find [caminho ...] expressão [ação]
O comando find
procura arquivos pelo nome ou outras características.
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:
Valores de c | Tipo de arquivo procurado |
b | Arquivo especial acessado a bloco |
c | Arquivo especial acessado a caractere |
d | Diretório |
p | Named pipe (FIFO) |
f | Arquivo normal |
l | Link simbólico |
s | Socket |
Unidade | Valor |
b | Bloco de 512 bytes (valor default) |
c | Caracteres |
k | Kilobytes (1024 bytes) |
w | Palavras (2 bytes) |
-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; |
Para usar mais de um critério de pesquisa, faça:
expressão1
expressão2
ou expressão1 -a expressão2
para atender aos critérios especificados por expressão1
e expressão2
; expressão1 -o expressão2
para atender aos critérios especificados por expressão1
ou expressão2
.
As principais ações definidas para ação são:
cmd
. O escopo de comando é considerado encerrado quando um ponto-e-vírgula (;) é encontrado. A cadeia {} é substituída pelo nome de cada arquivo que satisfaz ao critério de pesquisa e a linha assim formada é executada. Assim como foi dito para a opção name, o ponto-e-vírgula (;) deve ser precedido por uma contrabarra, ou deve estar entre aspas ou apóstrofos;
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 2004 ./.bash_logout Tue Nov 1 09:44:16 2005 ./.bash_profile Tue Nov 1 09:45:28 2005 ./.bashrc Fri Dec 23 20:32:31 2005 ./.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:
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) |
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 2005) |
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 2004 .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 2004-11-29 11:18:51 ./.bash_logout 2005-11-01 09:44:16 ./.bash_profile 2005-11-01 09:45:28 ./.bashrc 2005-12-26 17:35:13 ./.bash_history
Espero que o texto tenha sido útil.