Utilisez
find \( -path "./tmp" -o -path "./scripts" \) -prune -o -name "*_peaks.bed" -print
ou
find \( -path "./tmp" -o -path "./scripts" \) -prune -false -o -name "*_peaks.bed"
ou
find \( -path "./tmp" -path "./scripts" \) ! -prune -o -name "*_peaks.bed"
L'ordre est important. Il s'évalue de gauche à droite. Commencez toujours par l'exclusion du chemin.
Explication
Ne pas utiliser -not
(ou !
) pour exclure tout le répertoire. Utilisez -prune
. Comme expliqué dans le manuel :
−prune The primary shall always evaluate as true; it
shall cause find not to descend the current
pathname if it is a directory. If the −depth
primary is specified, the −prune primary shall
have no effect.
et dans le manuel GNU find :
-path pattern
[...]
To ignore a whole
directory tree, use -prune rather than checking
every file in the tree.
En effet, si vous utilisez -not -path "./pathname"
, find évaluera l'expression pour chaque nœud sous "./pathname"
.
Les expressions de recherche ne sont que des évaluations de conditions.
-
\( \)
- opération de groupe (vous pouvez utiliser -path "./tmp" -prune -o -path "./scripts" -prune -o
mais il est plus verbeux).
-
-path "./script" -prune
- si -path
retourne true et est un répertoire, retourne true pour ce répertoire et fait no y descendre.
-
-path "./script" ! -prune
- il est évalué comme (-path "./script") AND (! -prune)
. Il renverse le "toujours vrai" de prune en toujours faux. Il évite d'imprimer "./script"
comme une correspondance.
-
-path "./script" -prune -false
- depuis -prune
retourne toujours vrai, vous pouvez le suivre avec -false
pour faire la même chose que !
.
-
-o
- Opérateur OR. Si aucun opérateur n'est spécifié entre deux expressions, l'opérateur AND est utilisé par défaut.
D'où, \( -path "./tmp" -o -path "./scripts" \) -prune -o -name "*_peaks.bed" -print
est étendu à :
[ (-path "./tmp" OR -path "./script") AND -prune ] OR ( -name "*_peaks.bed" AND print )
L'empreinte est importante ici, car sans elle, il y a expansion :
{ [ (-path "./tmp" OR -path "./script" ) AND -prune ] OR (-name "*_peaks.bed" ) } AND print
-print
est ajouté par find - c'est pourquoi la plupart du temps, vous n'avez pas besoin de l'ajouter dans votre expression. Et puisque -prune
retourne vrai, il imprimera "./script" et "./tmp".
Ce n'est pas nécessaire dans les autres parce que nous avons échangé -prune
pour qu'il renvoie toujours false.
Conseil : Vous pouvez utiliser find -D opt expr 2>&1 1>/dev/null
pour voir comment il est optimisé et étendu,
find -D search expr 2>&1 1>/dev/null
pour voir quel chemin est vérifié.