Grep & Regular Expressions
Searching inside files with grep, matching patterns with regex, and finding files with find
Quick check before you start: Can you explain what
grepdoes? If not, read on. If you can already usegrep -nand write a basic regex, skip to Extended Regex.Practice this topic: Grep & Regex skill drill
After this lesson, you will be able to:
- Use
grepwith flags (-n,-i,-c,-v) to search for text inside files - Write basic regular expressions using
.,^,$,*, and[...] - Use extended regex (
-E) for+,?,|, and grouping - Use
findto locate files by name or type in a directory tree
grep: Search Inside Files
grep stands for Global Regular Expression Print. It reads lines and prints every line that matches a pattern:
grep "printf" main.c
This prints every line in main.c containing the text printf.
Essential Flags
| Flag | Effect | Example |
|---|---|---|
-n |
Show line numbers | grep -n "TODO" *.c |
-i |
Case-insensitive | grep -i "error" log.txt |
-c |
Count matches | grep -c "include" main.c |
-v |
Invert — show non-matching lines | grep -v "^#" config.txt |
-r |
Search recursively through directories | grep -r "main" src/ |
-l |
List filenames only (not matching lines) | grep -rl "TODO" . |
Combine flags freely:
grep -rn "malloc" src/ # recursive search with line numbers
grep -ci "error" build.log # case-insensitive count
Piping into grep
grep is a natural filter in pipelines:
ps aux | grep firefox # find firefox processes
ls /usr/bin | grep zip # find programs with "zip" in the name
history | grep "gcc" # find past gcc commands
Basic Regular Expressions
A regular expression (regex) is a pattern that describes a set of strings. grep uses regex by default.
| Metacharacter | Matches | Example | Matches |
|---|---|---|---|
. |
Any single character | h.t |
hat, hit, hot |
^ |
Start of line | ^# |
lines starting with # |
$ |
End of line | \.c$ |
lines ending in .c |
* |
Zero or more of previous | ab*c |
ac, abc, abbc |
[...] |
Any one character in set | [aeiou] |
any vowel |
[^...] |
Any character NOT in set | [^0-9] |
any non-digit |
Examples:
grep "^#include" main.c # lines starting with #include
grep "\.c$" filelist.txt # lines ending in .c (dot escaped with \)
grep "^$" notes.txt # empty lines
grep "[0-9]" data.txt # lines containing any digit
The backslash \ escapes a metacharacter. \. matches a literal dot, not “any character.”
Extended Regular Expressions
Use grep -E (or egrep) for extended regex, which adds:
| Metacharacter | Matches | Example |
|---|---|---|
+ |
One or more of previous | [0-9]+ — one or more digits |
? |
Zero or one of previous | colou?r — color or colour |
\| |
Alternation (OR) | cat\|dog — cat or dog |
(...) |
Grouping | (ab)+ — ab, abab, ababab |
grep -E "[0-9]+" scores.txt # lines with one or more digits
grep -E "^(int|char|double)" *.c # C lines starting with a type
grep -E "TODO|FIXME|HACK" -rn src/ # find all code annotations
find: Search for Files
While grep searches inside files, find searches for files by name, type, or other attributes:
find . -name "*.c" # all .c files under current directory
find . -name "*.c" -type f # only regular files (not directories)
find /home -name "*.txt" -size +1M # .txt files larger than 1 MB
Combine find and grep to search specific file types:
find . -name "*.c" -exec grep -ln "malloc" {} \;
This finds every .c file and searches each one for “malloc”, printing only filenames that match.
grep -v "^#" config.txt print?-v flag inverts the match — it prints lines that do NOT match the pattern. The pattern ^# means "starts with #". So grep -v "^#" prints every line that does not start with #. This is a common trick to strip comments from configuration files.
What Comes Next
You can now search file contents with grep and locate files with find. Next, you will learn what processes are and how to manage them.