First find the manual for find 🔎 :

man find

The find utility recursively descends the directory tree for each path listed, evaluating an expression (composed of the primaries'' and operands'' listed below) in terms of each file in the tree.

🤨

My co-worker explained it much better to me on Slack:

find is a program that lives in /usr/bin, and you'd usually use it to locate files or folders in your file system that match some filters or requirements.

Dechiper the cask command 🍺

The homebrew cask fix command we were dechipering yesterday started like this:

/usr/bin/find "$(brew --prefix)/Caskroom/"*'/.metadata'

I get the same output from that search if it starts with only find, but perhaps /usr/bin/find is a more fail-safe suggestion? Anyway, I got tripped up by it, because explainshell.com has nothing for /usr/bin/find so I started thinking it was “something else”.

The manual is incomprehensible, even the examples are horrible. 😖
Thank goodness for helpful co-workers:

The first argument is usually a folder, that you want to look in

And we checked the different outputs from these three:

brew --prefix
echo brew --prefix
echo $(brew --prefix)

So now I learnt that putting $() around something means the shell will run that before sending the argument to the program. Kinda like in maths! (And I understand what the --prefix does, but not what it is or where it comes from. Not mentioned in the brew manual. Hm.)

Glob patterns 🦃

Say what now? Thankfully Wikipedia describes it nicely:

glob patterns specify sets of filenames with wildcard characters * is a wildcard standing for "any string of characters" and *.txt is a glob pattern – Glob_(programming)

Familiar stuff, but phrasing was new(ish). Useful to read about other types of wildcard: ? for one character and [xyz] for one of the characters in the bracket. And glob is short for global! I’ll try to think of that in the future instead of how glob reminds me of gobbling as in turkeys.

Next, checking the different outputs from these:

echo *
echo /usr/local/*
echo "$(brew --prefix)/Caskroom/"*'/.metadata'
echo "$(brew --prefix)/Caskroom/"*'/.metadata' | tr " " "\n"

That last one echoes back to me what find will be given as an argument.

Some more actions for find 📖
-type f look for files
-type d look for directories
-name elisabeth look for my name
-name '*.css' look for names ending in dot css
-print display full pathname on each line
-delete delete all the files that matched
-exec send output from find as arguments to a program you want to run

With and without quotes

-name '*.rb' (notice the single quotes, they are important!) says that the file name should match the pattern *.rb. It has the same rule as the shell globs. But because it's in single quotes, the shell ignores it. So it's up to find to make sense of it instead.

The way I understand it, is that the moment you want to search something with a wildcard, you need quotes — otherwise the shell will try to act on the wildcard. Makes sense. (Any quotes? Or is there a difference between single and double?)


What I was confused about initially

I use a handful of commands that follow the same pattern, you write git, brew, cd, npm or whatever first, then something else follows. Something like /usr/bin/find and even man find break the pattern of starting with the name of the program. So while they’re not really anything brand new to me, I get lost on what the command is and where to learn more about it. Like, it’s not like I can search on the internet for “find”.

What I understand better now

  • I hadn’t entirely grasped what that means for me that Mac OS is Unix-based. Now I will remember that for example searching for unix find will point me in the right direction.
  • Look! A list of Unix commands with lots of words I know, but here they are put in relation to each other, which is always helpful for understanding something. 👈👈👈
  • man itself is also a unix command and I need to remember to use it.