Utilisation
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 évalue de gauche à droite. Commencez toujours par l'exclusion de chemin.
Explication
N'utilisez pas -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 de recherche de GNU:
-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 find ne sont que des évaluations de conditions.
\( \)
- fonctionnement des groupes (vous pouvez utiliser -path "./tmp" -prune -o -path "./scripts" -prune -o
, mais c'est plus verbeux).
-path "./script" -prune
- si -path
retourne true et est un répertoire, renvoie true pour ce répertoire et ne le fait pas descend dedans.
-path "./script" ! -prune
- il évalue comme (-path "./script") AND (! -prune)
. Cela change le "toujours vrai" du pruneau en toujours faux. Cela évite d'imprimer "./script"
en correspondance.
-path "./script" -prune -false
- puisque -prune
renvoie 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, la valeur par défaut est l'opérateur AND.
Par conséquent, \( -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'impression est ici importante car sans elle est étendue à:
{ [ (-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
renvoie true, il affichera "./script" et "./tmp".
Ce n'est pas nécessaire dans les autres car nous avons basculé -prune
pour toujours retourner faux.
Astuce: vous pouvez utiliser find -D opt expr 2>&1 1>/dev/null
pour voir comment il est optimisé et développé,
find -D search expr 2>&1 1>/dev/null
pour voir quel chemin est vérifié.
_peaks.bed
.