Finding Files and Folders
Objectives
By the end of this chapter, you should be able to:
- Compare and contrast
findandgrep - Use
findto search for files and folders, including wildcards - Use
grepflags to search text more precisely - Explain what a regular expression is, at a basic level
๐ก Why this matters:
findandgrepare two of the most-used commands in any developer’s day โ being fluent with them means never opening Spotlight, Alfred, or a GUI search box again.
Finding Files with find
find locates files and folders without any GUI search tool. The simplest form is find plus a name, searching from your current location:
find Downloads
Run from your home directory, that lists everything inside Downloads. (Point find at a folder rather than a file, and you get everything inside it too.)
For more control, find takes a path and an expression:
find . -name "first.txt"
That searches the current directory (.) for anything named exactly first.txt.
Wildcards with find
Three wildcard characters make find far more flexible:
*โ any number of characters?โ exactly one character[]โ any one of the characters listed inside the brackets
A few examples, assuming you’re searching the current folder:
- Anything ending in
.html:find . -name "*.html" - Anything with a three-letter extension, like
.txtor.css:find . -name "*.???" - Anything starting with
f,t, ors:find . -name "[fts]*" - Anything with
mainanywhere in the name:find . -name "*main*"
Searching Text with grep
Where find locates files and folders, grep searches inside text โ you already used it piped after cat in the last module. Given a file names.txt containing:
Lisa
Mark
Erin
Beth
Tim
Elizabeth
Tom
Matt
Liza
Janey
Jane
Shana
a handful of flags make grep much more precise:
| Flag | Does | Example |
|---|---|---|
-i |
Case-insensitive match | grep -i "erin" names.txt โ Erin |
-w |
Match whole words only | grep -iw "beth" names.txt matches only Beth, not Elizabeth |
-A N |
Show N lines after a match |
grep -A 3 "Beth" names.txt |
-B N |
Show N lines before a match |
grep -B 3 "Beth" names.txt |
-C N |
Show N lines around a match |
grep -C 3 "Beth" names.txt |
-v |
Invert โ show non-matching lines | grep -v "Jane" names.txt |
-c |
Count matches | grep -c "Jane" names.txt โ 2 |
-n |
Show line numbers | grep -ni "Jane" names.txt โ 10:Janey, 11:Jane |
There are more flags than this โ man grep has the full list.
Regular Expressions
Wildcards work with find, but searching text for a pattern instead of an exact word uses regular expressions โ a syntax for describing patterns in a string, powerful enough to validate an email address or phone number format. A full treatment is its own topic, but a few building blocks go a long way:
.matches any single character. How many names are exactly four characters long?grep -wc "...." names.txtโ7*matches zero or more of whatever precedes it. How many names start with a capitalT?grep -wc "T.*" names.txtโ2[]matches any one listed character. How many names start withL,M, orE?grep -wc "[LME].*" names.txtโ6[^]negates โ matches anything not listed. How many names don’t start withT?grep -wc "[^T].*" names.txtโ10
Try It
Both commands search your real filesystem and real files, so try these yourself:
- Pick a folder with a few files in it and use
findwith a wildcard to locate everything of one file extension. - Recreate the
names.txtfile above and confirm thegrep -wccounts for yourself. - Use
-A,-B, or-Cto print a few lines of context around a match in any text file you have handy.
Recap
findlocates files and folders, optionally using*,?, and[]wildcards.grepsearches inside text, and flags like-i,-w,-c, and-nnarrow that search down.- Regular expressions (
.,*,[],[^]) describe patterns rather than exact text, and work withgrepfar beyond what wildcards alone can do.
Next up: a set of exercises pulling together environment variables, processes, find, and grep.