Comment by IsTom

20 hours ago

`find` does a lot more things than that.

Definitely. The whole Unix philosophy of each command doing one thing and being easily composable always seemed to break down in my mind when it came to find. find does a lot.

similar to ripgrep, though, fd is a modern replacement that’s a bit friendlier to use.

  • find is absolute agony once you get a taste of fd.

    • I tried fd but it seems to ignore so much that it's basically useless. If I wanted `git ls-files|grep` I would `git ls-files|grep`

      yells at cloud

      ..it's probably ok actually and I should give it a real go, but I'm too used to find and even have a keybinding in my ~/.inputrc to insert a find + where loop

          "\e\C-f": "find . -type f -print0|while read -rd '' f; do ; done\e-b\C-b\C-b\C-b\C-b\C-b\C-b"
      

      (yes I know about -exec; I find the loop easier to work with)

> `find` does a lot more things than that.

And I don't think that's a good thing. Especially because AI coding agents use it a lot. They only need to hallucinate a little to destroy your filesystem.

It is just a query language for the filesystem, which is what "finding" means.

It's essentially like the SQL SELECT expression.

I'd wager that most people just don't get that the second "arg" (composed of multiple args) to find is an expression. Expressions are, somewhat unfortunately, code, so there's essentially a mini DSL there.

  find -name '*.md' -and -not -type d

Of course, then it becomes more obvious why there are parens, why those parens must be escaped for the shell, etc. E.g.,

  find '(' -name '*.md' -and -not -type d ')' -or '(' [...] ')'

I think once someone groks the nature of the expression args, then find becomes easier to start working with.

The most messed up part in my mind though is that while most things in find are clearly helping the expression towards its goal of "true" or "false" on whether to include the file or not in the results, some, like -prune or -exec do so but with side-effects. And since they're usually invoked primarily for their side-effect, it isn't immediately obvious that they even return a value, or are participating in the expression itself. (-prune is true, and -exec depends.) And this is where it becomes important that `find`'s -and & -or are short-circuiting, too. (In a purely logical expression, it wouldn't really matter except as an optimization.)

People also sometimes omit -and, which I'm not a huge fan of the legibility of. (But using -and makes it not POSIX; you can do -a but ew. which brings me to the last bit…)

macOS: the find there requires the starting-point arg; so my examples above, on macOS, would all need to be,

  find . [expression args...]

… which is lame. Brew install GNU find and be done with that.

While I agree with globbing (or fd) for interactive use, I think for scripting I'd still say "you might want find"; there are limits to arg list lengths (see xargs) that (esp. recursive) globs can exceed; unless you know you'll never glob the world, find might be appropriate. Also:

  echo *nope*

Globs will betray you on the zero-match case. (`man bash` & cf. `nullglob`.)