Skip to content
Latchkey

find -not, -o, -a: Combine Conditions

find joins predicates with -and, -or, and -not, grouped by escaped parentheses.

Real searches need logic: this name but not that path, files of either extension. Knowing precedence and grouping prevents silent mismatches.

What it does

find combines tests with operators: -a (or -and, the implicit default between predicates), -o (or -or), and ! (or -not) to negate. -a binds tighter than -o, so use escaped parentheses \( \) to group when mixing them. Negation applies to the predicate that follows.

Common usage

Terminal
find . -type f ! -name '*.min.js'
find . \( -name '*.js' -o -name '*.ts' \) -type f
find . -type f -not -path '*/node_modules/*'

Options

OperatorWhat it does
-a / -andLogical AND (implicit between predicates)
-o / -orLogical OR (lower precedence than AND)
! / -notNegate the following predicate
\( ... \)Group expressions to control precedence

In CI

Because AND binds tighter than OR, find . -name a -o -name b -type f does not mean what it looks like. Wrap the alternation: find . \( -name a -o -name b \) -type f. Combine ! -path with -prune-free patterns to exclude vendored directories.

Common errors in CI

"find: paths must precede expression" often comes from unescaped parentheses the shell interpreted; write \( \) or quote them. "find: invalid expression; you have used a binary operator -o with nothing before it" means an -o sits at the start of a group or after another operator. Forgetting to group -o lets -type f apply to only one branch.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →