findr - finding files without flags

I am impressed by the sheer amount of functionality offered by the Unix find command, but remain unable to remember how to use it for anything other than the basics; otherwise I hit Google. I don't have a very good memory for flags, but I do remember expressions. findr is given exactly two arguments; the base directory and a filter expression:

$ findr . 'path.ext=="rs" && path.size > 1kb' $ findr . 'path.is_file && date.before("1 jan")' $ findr . 'path.ext=="md" and date.after("last tuesday")'

The filter expression is passed path, date and mode and fairly arbitrary expressions are supported, thanks to the very capable little embedded language rhai. As a little convenience, "and", "or" and "not" are understood, since these are easier to type in a hurry.

path has the following fields:

There's also a matches method (e.g. path.matches("*/readme.*")).

date has the following methods:

mode is just the usual Unix permission bits - expressions may contain octal constants in Rust notation (e.g. 0o755)

Numbers may have a size prefix (kb,mb,gb - not case-sensitive) and date strings are interpreted by chrono-english.

Currently, findr ignores hidden directories and files excluded by .gitignore. It has not been entirely possible to do without flags!

``` ~$ findr -h findr: find files and filter with expressions

-n, --no-hidden look at hidden files and follow hidden dirs -g, --no-gitignore do not respect .gitignore -m, --manual show more detailed help about findr

(path) base directory to start traversal (default 'true') filter paths

```

By default, it speaks British English dates (i.e. not "9/11"), unless the environment variable FINDR_US is defined.

Respecting .gitignore is something that makes your life easier if you are not particularly interested in build artifacts. It is particularly useful in Rust projects because incremental compilation generates a lot of intermediate build artifacts.

With findr, I can now finally answer the question "What the f*k did I do on Tuesday?":

~$ findr . 'date.on("last tues")' ./rust/repos/findr/src/errors.rs ./rust/scratch ./rust/scratch/over/test.over ./rust/scratch/over/type1.over ./rust/scratch/over/over.rs ./rust/scratch/over/empty.over ./rust/scratch/over/tuple.over ./rust/scratch/over/strs.over ./rust/scratch/over/main.over ./rust/scratch/over/id.over ./rust/scratch/over/numbers.over ./rust/scratch/over/strings.over ./rust/scratch/over/map.over ./rust/scratch/over/str.over ./rust/scanlex/src ./rust/scanlex/src/lib.rs With the -g flag (ignore .gitignore) there are 538 files changed on that day!

To illustrate my point about flag madness, the equivalent of findr . 'path.ext="rs"' is:

find . -type d -path '*/\.*' -prune -o -not -name '.*' -type f -name '*.rs' -print

(I had to look that one up)