`grep` for testers
grep
finds lines that match a pattern – so it's used when you want to sift useful information out of something bigger.
grep
works on streams rather than necessarily on files, so can be chained with tools which output information. Example: ls | grep .json
will list the names of all the files in the current directory* (ls
), and only output those names which contain .json
. That pipe |
connects an output to an input, reading left to right, so connects the output of ls
to the input of grep
. * current directory – if you're working on the command line, you're always working on one, and only one, folder or directory.
grep
outputs a stream, so it can be used in the middle of a chain of tools. Example: ls -R | grep .json | wc -l
will list the names of all the files in the current directory and below (ls -R
), filter just the ones that contain .json
, then count those lines – giving you a count of all those files.
grep
will also work on files. You put a filename after the thing you're looking for. Think grep
for«a thing»
in(these) file(s)
. Example: grep 'Factory Error' apache.log
will show all lines containing Factory error
in a file called Apache.log
in your current directory.
grep
's searching is based on regex, so you may need to work (and test) to get the search right before trusting the output. Don't live with the pain: use a regex painter like regexr, regex generator, regex101.
Handy grep
for testers
Some things I've used recently (I'll add to this...).
Is a process running?
ps -ef | grep [a]pache
will show you any processes running called apache
... more usefully, it will show nothing if apache
isn't running.
If you just ps -ef | grep apache
(as I did until writing this page), you'll get back the process that is looking for the word apache
, too. You'll get used to this behaviour, but it's less good if you're automating.
Handy if you expect your process to be running, and you don't want to scan the list. Obvs you need to know your process name, and to be happily on the command line. Use ps aux
if you prefer.
What's the context for any fatal errors?
grep -C 10 fatal Apache.log
would show you any line in Apache.log
with the word fatal
in it, and ten lines above and below. Change to suit your logs: I've never seen fatal
in an Apache log.
Handy for seeing what happened immediately before and after a problem.
Where are the logs?
ls -R | grep log
will find all file names / directory names with the characters log
in them, in and below your current directory. Handy if you need a swift scan for files with particular names, and you find find
confusing. As I do.
grep -R log .
will find all files with the characters log
anywhere in the file, in all the files in and below your current directory.
A note on finding files and recursion
ls -r
produces a list of files, and grep
just sees that list as text. So grep
doesn't know the path or the file context – and it just shows the filename.
grep -r «whatever» .
works recursively through a directory: it knows the path and looks inside the file for the content, not at the name
If you want to use grep
to search filenames, it'll work but it's compromised. I might use find . -type f -name "*.log"
, which would find all files (and only files) ending with the characters .log
. So I'm putting that here to remind me.
What files contain the word forbidden
?
grep -r forbidden .
will find forbidden
in all files below this directory (-r
for recursive – or you can use -R
for differently recursive), while...
grep -r -i forbidden .
is case-insensitive and will find Forbidden
, fOrBiDdEn
etc.
Handy for spotting what code references specific modules, functions or data; for pulling out all error messages, text or regex; for highlighting comments with todo
or bug
, for searching logs and manuals...
Most IDEs already give you the facility to search across all files in a project. Using grep
is handier if you're using something to process what you find.
Variant: What IP addresses are specified directly?
grep -r -E "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" .
will look in lots of files for that (-E
means extended regex) pattern. That confusing barrage of detail (ask an LLM to parse it) should pickup IP addresses (and some things that look like IP addresses, and aren't).
Handy for spotting when your code has hard-coded IP addresses, or for grabbing the things out of a directory full of config files, or from logs.
Show me whenever the log file flags an error
Using a dedicated terminal window, and in the right directory, run the command tail -F «logfile.log» | grep -i -E "error|fatal|failure|spin"
and that window will be a realtime view of the most-recent end of the log, and will show only those lines which include the selected words. Note that we're using tail -F
, not tail -f
, which should follow the logfile if something else changes it by making it a new file.
The files are compressed!
Use zgrep
to look inside compressed files, too. It may not extract the info, but it will tell you that it's there.
I want everything except what I'm asking for
Use grep -v
to return lots of stuff. Maybe you're seeking every line in the log which doesn't have a specific IP address.
I want to look for two things and I don't want to write regex.
Good choice. Regex is human-unreadable. Stack your grep
s.
Example: tail -F «log» | grep "failure" | grep "core"
Two things, one or the other?
Example: tail -F «log» | grep -e "failure" -e "core"
or: tail -F «log» | grep -e "failure\|core"
, which has fewer keystrokes but is harder to read.
More
Playgrounds – interactive grep in browser

Workroom Exercises

Other people's interactive exercises


Alternatives / similar tools
grep
is >50 years old. These aren't. Currently.


Sources and quickreferences

https://www.gnu.org/software/grep/
https://www.gnu.org/software/grep/manual/grep.html





Comments
Sign in or become a Workroom Productions member to read and leave comments.