Searching Text with grep
Prerequisites: Pipes: connecting commands
grep finds lines matching a pattern — in files, or in the output of
other commands. It's one of the most used command-line tools.
cat > app.log <<'EOF'
2025-04-22 09:00:01 INFO Server started on port 8080
2025-04-22 09:05:12 WARN Slow response from db (1200ms)
2025-04-22 09:07:44 ERROR Payment failed for order 1042
2025-04-22 09:08:02 info Health check ok
2025-04-22 09:12:30 ERROR Timeout calling inventory service
EOF
grep "ERROR" app.log
echo "---"
grep -i "info" app.log
echo "---"
grep -n "WARN" app.log
echo "---"
grep -c "ERROR" app.log
2025-04-22 09:07:44 ERROR Payment failed for order 1042
2025-04-22 09:12:30 ERROR Timeout calling inventory service
---
2025-04-22 09:00:01 INFO Server started on port 8080
2025-04-22 09:08:02 info Health check ok
---
2:2025-04-22 09:05:12 WARN Slow response from db (1200ms)
---
2
| Option | Does |
|---|---|
-i |
ignore case |
-n |
show line numbers |
-c |
count matching lines |
-v |
show lines that don't match |
-w |
match whole words only |
-r |
search files in folders recursively |
-l |
list only the names of matching files |
-o |
print only the matching part |
-A 2 / -B 2 / -C 2 |
lines of context after / before / around |
Regular expressions
grep -E uses extended regular expressions:
cat > app.log <<'EOF'
2025-04-22 09:07:44 ERROR Payment failed for order 1042
2025-04-22 09:12:30 ERROR Timeout calling inventory service
2025-04-22 09:15:00 WARN Retrying order 1043
EOF
grep -E "ERROR|WARN" app.log | wc -l
grep -oE "order [0-9]+" app.log
grep -oE "[0-9]{2}:[0-9]{2}" app.log | head -n 2
3
order 1042
order 1043
09:07
09:12
|means "or";[0-9]+means one or more digits;{2}means exactly two.-oextracts just the matched text — great for pulling IDs, emails, or numbers out of text.
Build and test patterns in the Regex Tester.
Searching a project
mkdir -p src/utils
echo "// TODO: add caching" > src/api.js
echo "const x = 1;" > src/utils/math.js
echo "// TODO: handle errors" > src/utils/net.js
grep -rn "TODO" src | sort
echo "---"
grep -rl "TODO" src | sort
src/api.js:1:// TODO: add caching
src/utils/net.js:1:// TODO: handle errors
---
src/api.js
src/utils/net.js
Common mistakes
- Special characters in patterns:
.matches any character. Search for a literal dot with\.or usegrep -F(fixed strings, no regex). - Forgetting quotes around the pattern, so the shell expands
*or?beforegrepsees them.