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 -pathretourne 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 -prunerenvoie toujours vrai, vous pouvez le suivre avec -falsepour 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" -printest é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
-printest ajouté par find - c'est pourquoi la plupart du temps, vous n'avez pas besoin de l'ajouter dans votre expression. Et puisque -prunerenvoie 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/nullpour voir comment il est optimisé et développé,
find -D search expr 2>&1 1>/dev/nullpour voir quel chemin est vérifié.
_peaks.bed.