{{tag>find bash}}
= Find prune
Trouver des prunes ou ''find -prune''
C'est vrai que notre ami GNU find est efficace, rapide etc....
Mais quand nous voulons cherchez dans une arborescence il arrive que nous souhaitons exclure des répertoires.
Un façon de faire est ''-not -wholename''
Ça marche, donc où est le problème ?
Et bien si nous suivons ce que fait find à l'aide de la commande ''strace'', nous nous apercevons qu'il recherche malgré tout dans le dossier qu'y était pourtant exclu.
Dans notre exemple, nous avons un dossier **1wpixwnr.default** dans **.thunderbird**\\
Et nous voulons tous les fichiers du répertoire courant sauf ceux présents dans **.thunderbird**
Ici nous constatons que find va dans **.thunderbird**, puisqu'il ouvre **1wpixwnr.default**
# strace find . -not -wholename ".thunderbird/*" 2>&1 |grep '1wpixwnr.default'|grep ^open
open("1wpixwnr.default", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 5
Même chose ici
# strace find . -not -wholename "./.thunderbird/*" 2>&1 |grep '1wpixwnr.default'|grep ^open
open("1wpixwnr.default", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 5
Alors qu'avec des prunes, il n'y a que les accès disque nécessaires
strace find . -wholename "./.thunderbird/*" -prune -o -print 2>&1 |grep '1wpixwnr.default'|grep ^open
Attention cependant, ici même avec prune, il y a des accès disques inutiles
# strace find . -wholename ".thunderbird/*" -prune -o -print 2>&1 |grep '1wpixwnr.default'|grep ^open
open("1wpixwnr.default", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 5
Notons qu'ici **.thunderbird** est inclus dans le résultat :
$ find . -wholename "./.thunderbird/*" -prune -o -print |grep '\.thunderbird'
./.thunderbird
A présent comparons :
$ time find . -not -wholename "./Ziques/*" >/dev/null
real 0m0.321s
user 0m0.170s
sys 0m0.140s
(encore une fois)
$ time find . -not -wholename "./Ziques/*" >/dev/null
real 0m0.321s
user 0m0.170s
sys 0m0.140s
$ time find . -wholename "./Ziques/*" -prune -o -print >/dev/null
real 0m0.138s
user 0m0.100s
sys 0m0.030s
Alors que le résultat est identique :
diff <(find . -not -wholename "./Ziques/*") <(find . -wholename "./Ziques/*" -prune -o -print)
Quelques liens sur find -prune que je n'ai pas vraiment eu le temps de lire.
[[http://www.developpez.net/forums/d133567/systemes/linux/applications/shell/option-prune-commande-find/]]
[[http://www.liamdelahunty.com/tips/linux_find_exclude_multiple_directories.php]]
[[http://www.liamdelahunty.com/tips/linux_find_prune_directory.php]]
[[http://dit-archives.epfl.ch/FI94/5-94-page15.html]]
Exemple :
Trouvez tous les mp3 qui ne sont pas dans ./backup/Ziques :
find . -type f -iname "*.mp3" \( -wholename "./backup/Ziques/*" -prune -o -print \)
Évidement on peut faire :
find . -type f -iname "*.mp3" -not -wholename "./backup/Ziques/*"
Mais dans ce cas find ira quand même dans l'arborescence ./backup/Ziques et ça peut être long !