TLDR: entenda seus diretórios raiz e adapte sua pesquisa a partir daí, usando a -path <excluded_path> -prune -o
opção Não inclua um final /
no final do caminho excluído.
Exemplo:
find / -path /mnt -prune -o -name "*libname-server-2.a*" -print
Para usar efetivamente o find
, acredito que é imperativo ter um bom entendimento da estrutura de diretórios do sistema de arquivos. No meu computador doméstico, eu tenho discos rígidos com vários TB, com cerca de metade desse conteúdo sendo copiada usando rsnapshot
(ou seja, rsync
). Embora faça backup em uma unidade fisicamente independente (duplicada), ela é montada no /
diretório raiz ( ) do meu sistema /mnt/Backups/rsnapshot_backups/
::
/mnt/Backups/
└── rsnapshot_backups/
├── hourly.0/
├── hourly.1/
├── ...
├── daily.0/
├── daily.1/
├── ...
├── weekly.0/
├── weekly.1/
├── ...
├── monthly.0/
├── monthly.1/
└── ...
O /mnt/Backups/rsnapshot_backups/
diretório atualmente ocupa ~ 2,9 TB, com ~ 60M de arquivos e pastas; simplesmente atravessar esses conteúdos leva tempo:
## As sudo (#), to avoid numerous "Permission denied" warnings:
time find /mnt/Backups/rsnapshot_backups | wc -l
60314138 ## 60.3M files, folders
34:07.30 ## 34 min
time du /mnt/Backups/rsnapshot_backups -d 0
3112240160 /mnt/Backups/rsnapshot_backups ## 3.1 TB
33:51.88 ## 34 min
time rsnapshot du ## << more accurate re: rsnapshot footprint
2.9T /mnt/Backups/rsnapshot_backups/hourly.0/
4.1G /mnt/Backups/rsnapshot_backups/hourly.1/
...
4.7G /mnt/Backups/rsnapshot_backups/weekly.3/
2.9T total ## 2.9 TB, per sudo rsnapshot du (more accurate)
2:34:54 ## 2 hr 35 min
Assim, sempre que eu precisar procurar um arquivo na minha /
partição (raiz), preciso lidar com (evitar se possível) atravessar minha partição de backups.
EXEMPLOS
Entre as abordagens sugeridas de várias maneiras neste tópico ( Como excluir um diretório no comando find. ), Acho que as pesquisas usando a resposta aceita são muito mais rápidas - com ressalvas.
Solução 1
Digamos que desejo encontrar o arquivo do sistema libname-server-2.a
, mas não desejo pesquisar nos meus rsnapshot
backups. Para localizar rapidamente um arquivo do sistema, use o caminho de exclusão /mnt
(por exemplo, use /mnt
, not /mnt/
, ou /mnt/Backups
, ou ...):
## As sudo (#), to avoid numerous "Permission denied" warnings:
time find / -path /mnt -prune -o -name "*libname-server-2.a*" -print
/usr/lib/libname-server-2.a
real 0m8.644s ## 8.6 sec <<< NOTE!
user 0m1.669s
sys 0m2.466s
## As regular user (victoria); I also use an alternate timing mechanism, as
## here I am using 2>/dev/null to suppress "Permission denied" warnings:
$ START="$(date +"%s")" && find 2>/dev/null / -path /mnt -prune -o \
-name "*libname-server-2.a*" -print; END="$(date +"%s")"; \
TIME="$((END - START))"; printf 'find command took %s sec\n' "$TIME"
/usr/lib/libname-server-2.a
find command took 3 sec ## ~3 sec <<< NOTE!
... encontra esse arquivo em apenas alguns segundos, enquanto isso leva muito mais tempo (parecendo ser repetido em todos os diretórios "excluídos"):
## As sudo (#), to avoid numerous "Permission denied" warnings:
time find / -path /mnt/ -prune -o -name "*libname-server-2.a*" -print
find: warning: -path /mnt/ will not match anything because it ends with /.
/usr/lib/libname-server-2.a
real 33m10.658s ## 33 min 11 sec (~231-663x slower!)
user 1m43.142s
sys 2m22.666s
## As regular user (victoria); I also use an alternate timing mechanism, as
## here I am using 2>/dev/null to suppress "Permission denied" warnings:
$ START="$(date +"%s")" && find 2>/dev/null / -path /mnt/ -prune -o \
-name "*libname-server-2.a*" -print; END="$(date +"%s")"; \
TIME="$((END - START))"; printf 'find command took %s sec\n' "$TIME"
/usr/lib/libname-server-2.a
find command took 1775 sec ## 29.6 min
Solução 2
A outra solução oferecida neste segmento ( SO # 4210042 ) também apresenta desempenho ruim:
## As sudo (#), to avoid numerous "Permission denied" warnings:
time find / -name "*libname-server-2.a*" -not -path "/mnt"
/usr/lib/libname-server-2.a
real 33m37.911s ## 33 min 38 sec (~235x slower)
user 1m45.134s
sys 2m31.846s
time find / -name "*libname-server-2.a*" -not -path "/mnt/*"
/usr/lib/libname-server-2.a
real 33m11.208s ## 33 min 11 sec
user 1m22.185s
sys 2m29.962s
RESUMO CONCLUSÕES
Use a abordagem ilustrada em " Solução 1 "
find / -path /mnt -prune -o -name "*libname-server-2.a*" -print
ie
... -path <excluded_path> -prune -o ...
observando que sempre que você adiciona a /
trilha ao caminho excluído, o find
comando entra recursivamente nos /mnt/*
diretórios (todos esses) - que, no meu caso, por causa dos /mnt/Backups/rsnapshot_backups/*
subdiretórios, inclui adicionalmente ~ 2,9 TB de arquivos a serem pesquisados! Ao não anexar uma trilha, /
a pesquisa deve ser concluída quase imediatamente (em segundos).
A "Solução 2" ( ... -not -path <exclude path> ...
) também parece procurar recursivamente os diretórios excluídos - não retornando correspondências excluídas, mas consumindo desnecessariamente esse tempo de pesquisa.
Pesquisando nesses rsnapshot
backups:
Para localizar um arquivo em um dos meus rsnapshot
backups horários / diários / semanais / mensais ):
$ START="$(date +"%s")" && find 2>/dev/null /mnt/Backups/rsnapshot_backups/daily.0 -name '*04t8ugijrlkj.jpg'; END="$(date +"%s")"; TIME="$((END - START))"; printf 'find command took %s sec\n' "$TIME"
/mnt/Backups/rsnapshot_backups/daily.0/snapshot_root/mnt/Vancouver/temp/04t8ugijrlkj.jpg
find command took 312 sec ## 5.2 minutes: despite apparent rsnapshot size
## (~4 GB), it is in fact searching through ~2.9 TB)
Excluindo um diretório aninhado:
Aqui, quero excluir um diretório aninhado, por exemplo, /mnt/Vancouver/projects/ie/claws/data/*
ao pesquisar em /mnt/Vancouver/projects/
:
$ time find . -iname '*test_file*'
./ie/claws/data/test_file
./ie/claws/test_file
0:01.97
$ time find . -path '*/data' -prune -o -iname '*test_file*' -print
./ie/claws/test_file
0:00.07
Além: A adição -print
no final do comando suprime a impressão do diretório excluído:
$ find / -path /mnt -prune -o -name "*libname-server-2.a*"
/mnt
/usr/lib/libname-server-2.a
$ find / -path /mnt -prune -o -name "*libname-server-2.a*" -print
/usr/lib/libname-server-2.a