TLDR: comprenez vos répertoires racine et personnalisez votre recherche à partir de là, en utilisant l' -path <excluded_path> -prune -o
option. Ne pas inclure de fin/
à la fin du chemin exclu.
Exemple:
find / -path /mnt -prune -o -name "*libname-server-2.a*" -print
Pour utiliser efficacement le find
je pense qu'il est impératif d'avoir une bonne compréhension de la structure de répertoire de votre système de fichiers. Sur mon ordinateur personnel, j'ai des disques durs multi-To, avec environ la moitié de ce contenu sauvegardé à l'aide rsnapshot
(c'est-à-dire rsync
). Bien que la sauvegarde sur un lecteur physiquement indépendant (en double), il est monté sous mon /
répertoire racine système ( ) /mnt/Backups/rsnapshot_backups/
:
/mnt/Backups/
└── rsnapshot_backups/
├── hourly.0/
├── hourly.1/
├── ...
├── daily.0/
├── daily.1/
├── ...
├── weekly.0/
├── weekly.1/
├── ...
├── monthly.0/
├── monthly.1/
└── ...
Le /mnt/Backups/rsnapshot_backups/
répertoire occupe actuellement environ 2,9 To, avec environ 60 millions de fichiers et dossiers; traverser simplement ces contenus prend du temps:
## 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
Ainsi, chaque fois que je dois rechercher un fichier sur ma /
partition (racine), je dois gérer (éviter si possible) la traversée de ma partition de sauvegarde.
EXEMPLES
Parmi les différentes approches suggérées dans ce fil ( Comment exclure un répertoire dans la commande find. ), Je trouve que les recherches en utilisant la réponse acceptée sont beaucoup plus rapides - avec des mises en garde.
Solution 1
Disons que je veux trouver le fichier système libname-server-2.a
, mais je ne veux pas parcourir mes rsnapshot
sauvegardes. Pour trouver rapidement un fichier système, utilisez le chemin d'exclusion /mnt
(c'est-à-dire, utilisez /mnt
, pas /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!
... trouve ce fichier en quelques secondes, alors que cela prend beaucoup plus de temps (apparaissant comme récurrent dans tous les répertoires "exclus"):
## 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
Solution 2
L'autre solution proposée dans ce fil ( SO # 4210042 ) fonctionne également mal:
## 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
RÉSUMÉ | CONCLUSIONS
Utilisez l'approche illustrée dans la " Solution 1 "
find / -path /mnt -prune -o -name "*libname-server-2.a*" -print
c'est à dire
... -path <excluded_path> -prune -o ...
notant que chaque fois que vous ajoutez la fin /
au chemin exclu, la find
commande entre alors récursivement (tous ces) /mnt/*
répertoires - qui dans mon cas, en raison des /mnt/Backups/rsnapshot_backups/*
sous - répertoires, comprend en outre ~ 2,9 To de fichiers à rechercher! En n'ajoutant pas de fin/
la recherche devrait se terminer presque immédiatement (en quelques secondes).
La "Solution 2" ( ... -not -path <exclude path> ...
) semble également rechercher récursivement dans les répertoires exclus - ne renvoyant pas les correspondances exclues, mais consommant inutilement ce temps de recherche.
Recherche dans ces rsnapshot
sauvegardes:
Pour rechercher un fichier dans l'une de mes rsnapshot
sauvegardes horaires / quotidiennes / hebdomadaires / mensuelles ):
$ 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)
Exclusion d'un répertoire imbriqué:
Ici, je veux exclure un répertoire imbriqué, par exemple /mnt/Vancouver/projects/ie/claws/data/*
lors de la recherche à partir de /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
En plus: l' ajout -print
à la fin de la commande supprime l'impression du répertoire exclu:
$ 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
find ... | while read -r file ...
. En outre, il vaut mieux accepter et voter positivement.for file in $(find .); do echo "$file"; done
. Les noms avec des espaces sont divisés, ce que nous ne voulons pas.