Learn › Linux Foundations › Text Processing
grep - a hands-on Linux lab on a real virtual machine.
Search text with grep: print the lines that match a word, then the flags an engineer reaches for. Count with -c, number with -n, ignore case with -i, invert with -v, and match whole words or whole folders with -w and -r. Meet the no-match (nothing, exit 1) and the missing-file error, all in the practice terminal on a tiny fruits.txt fixture.
A log file scrolls past for a thousand lines and somewhere in there is the one word that tells you what broke: error. Reading every line to find it is not a plan. You need a command that reads the file for you and prints back ONLY the lines that contain what you are hunting for.
That command is grep. Hand it a word and a file, and it throws away every line that does not contain the word and keeps every line that does. It is the single most used text tool on Linux, and by the end of this lesson you will reach for it without thinking.
The black boxes in this lesson are a practice terminal: a safe sandbox that only checks the one command each step teaches, so you cannot break anything. At the end of the module one real Linux machine boots just for you and you run the full mission there.
grep searches text for a pattern, a piece of text you are looking for, and prints the lines that contain it. The plainest form is grep PATTERN FILE: the word you want, then the file to look in. Every line that holds the word is printed; every line that does not is silently dropped.
The name looks like nonsense until you know the story. It comes from an old text editor command, g/re/p, which meant "globally search for a regular expression and print." The name stuck, became a standalone tool, and turned into a verb. Engineers say "grep the logs" the way other people say "search the logs."
For this whole lesson you are working with one tiny file, fruits.txt. It has exactly four lines, in this order: apple, then banana, then cherry, then apple again. That is the entire file. Keep those four lines in mind, because every output below comes straight from them.
Start with the plainest search there is. Look for every line that contains apple:
grep apple fruits.txt
prompt: student@linuxcamp:~$ answer: grep apple fruits.txt output: apple apple hint: Type grep, a space, the word apple, a space, then the file: grep apple fruits.txt
Two lines came back, both reading apple. The file has four lines, but only the first and the last contain the word apple, so those are the two grep kept. banana and cherry were dropped without a word, because they did not match. That is the whole idea: matching lines print, everything else vanishes.
Sometimes you do not want to see the matching lines, you just want to know HOW MANY there are. The -c flag, short for count, prints a single number: how many lines matched. It does not print the lines themselves, only the tally.
Before you run it, you already know the answer from the last step: two lines matched. So -c should report exactly that. Ask for the count:
grep -c apple fruits.txt
prompt: student@linuxcamp:~$ answer: grep -c apple fruits.txt output: 2 hint: Add -c between grep and the pattern: grep -c apple fruits.txt
A single 2, no lines. That matches what you saw a moment ago: two lines contained apple, so the count is 2. One honest detail worth pinning: -c counts matching LINES, not matches. A line that contained the word twice would still add just 1 to the count. For our fixture that distinction does not bite, but remember it exists.
When you find a match in a big file, the next question is always "which line is that?" The -n flag, short for number, prints the line number in front of every matching line, then a colon. It turns a match into an address you can jump to.
Run the same apple search, but this time ask which lines they were:
grep -n apple fruits.txt
prompt: student@linuxcamp:~$ answer: grep -n apple fruits.txt output: 1:apple 4:apple hint: Add -n between grep and the pattern: grep -n apple fruits.txt
Now each line carries its address. 1:apple says the first apple is on line 1; 4:apple says the second is on line 4. That lines up exactly with the file: apple is line 1, banana line 2, cherry line 3, apple line 4. The number and the colon are added by grep; the text after the colon is the real line from the file.
By default grep is picky about capital letters. apple and APPLE are different text to it, so searching for one will not find the other. Most of the time that is fine, but often you do not care about case, you just want the word however it is spelled. The -i flag, short for ignore case, tells grep to treat capital and lowercase letters as the same.
Every line in fruits.txt is lowercase, so a plain search for APPLE would find nothing. Watch -i fix that. Search for APPLE in shouting capitals, but ignore the case:
grep -i APPLE fruits.txt
prompt: student@linuxcamp:~$ answer: grep -i APPLE fruits.txt output: apple apple hint: Add -i between grep and the pattern: grep -i APPLE fruits.txt
Both apple lines came back, even though you typed APPLE and the file holds apple. That is -i at work: it made the capitals in your pattern match the lowercase in the file. Drop the -i and search APPLE again and you would get nothing at all, because without it the capitals must line up letter for letter.
This is the one that surprises people, so meet it here in the sandbox. The -v flag, short for invert, turns the whole search inside out. Instead of printing the lines that match, it prints the lines that do NOT match. It is how you say "show me everything EXCEPT the lines with this word."
You know apple is on lines 1 and 4. So inverting the search should hand you the other two lines, banana and cherry. Try it:
grep -v apple fruits.txt
prompt: student@linuxcamp:~$ answer: grep -v apple fruits.txt output: banana cherry hint: Add -v between grep and the pattern: grep -v apple fruits.txt
The two apple lines are gone. The two that survived are banana and cherry, the lines with no apple in them. That is -v: same file, same pattern, opposite selection. It is priceless for filtering noise, such as "show me every log line that is NOT a routine heartbeat."
Two things happen often enough that you should see them plainly before they confuse you.
First, a search that finds nothing. grep does not print an error and does not say "no results." It simply prints nothing at all and hands back a quiet exit status of 1. The fixture has no pear in it, so searching for one prints an empty result:
grep pear fruits.txt
prompt: student@linuxcamp:~$ answer: grep pear fruits.txt output: hint: Type grep, a space, pear, a space, then the file: grep pear fruits.txt
Nothing printed, and that is the correct, complete answer. grep uses an invisible exit status to report the outcome: 0 when at least one line matched, 1 when none did. You do not see it on screen, but scripts read it constantly. grep -q word file && echo found is the classic use: search silently, then act on whether it matched. -q is covered when you reach scripting; for now just know a no-match is 1, not an error.
Second, a file that does not exist. If you point grep at a filename it cannot find, it says so plainly:
grep: nofile: No such file or directory
That is a real, complete error message, not a crash. It means grep looked for a file named nofile in the current folder and there was none. What to check first: the spelling of the filename, and whether you are standing in the folder that actually holds it. A quick ls shows you what names really exist to search.
You have the core. Two more flags round out the everyday kit, and you will use both constantly once you leave the sandbox.
-w, short for word, matches only whole words. A plain grep on file would match on, onward, and bacon, because the letters on appear inside all three. grep -w on file matches only the standalone word on. It is how you stop a short pattern from matching pieces of longer words.
-r, short for recursive, searches every file inside a folder and all its subfolders instead of one named file. grep -r error /var/log hunts the word error through the entire log directory tree at once, printing each matching line with the filename it came from. It turns grep from a one-file tool into a whole-project search.
There is one more flag you will see everywhere, -E, for extended regular expressions. It unlocks patterns that mean more than plain text, such as "match either of these two words." That is a language of its own, and it has its own lesson later in this module. For now, know the flag exists and that plain grep already does the everyday job.
Scaffolding off. No command is shown this time. You have every piece you need.
You are looking at fruits.txt again, the same four lines: apple, banana, cherry, apple. This time you want to see every line that is NOT an apple line, and nothing else. Pick the flag that flips a search around, and point grep at the file.
prompt: student@linuxcamp:~$ answer: grep -v apple fruits.txt output: banana cherry hint: Everything EXCEPT means invert the match. That is the -v flag: grep -v apple fruits.txt
banana and cherry, from memory. By choosing -v you told grep to keep the lines that do NOT contain apple, so the two apple lines dropped out and the other two printed. That is the whole skill: decide whether you want the matches or the non-matches, pick the flag, and type it without a prompt. It is exactly the move the real machine will ask of you.
You earned this cheat sheet. Every row is a form of grep you have already run or can now read at a glance:
And the one quiet fact behind it all: grep exits 0 when it found a match and 1 when it did not. A search that prints nothing is not broken, it simply matched nothing.
grep is at its most powerful when it reads the OUTPUT of another command instead of a file. Later in the camp you will send one command's output into grep to keep only the lines you care about, such as listing running programs and grepping for the one you want. The searching skill you built here is the same one.
The practice terminal has shown you every everyday form of grep. You have the plain pattern search, -c to count, -n for line numbers, -i to ignore case, and -v to invert, plus -w and -r for whole words and whole folders. You also saw the two things that trip people up: a no-match prints nothing and exits 1, and a missing file prints No such file or directory.
The Text Processing module ends with one real Linux machine, the text-processing capstone mission, and that is where you grep for real. A VM boots just for you, with real log files and lists to search. Its objectives use exactly what you practiced here alongside the module's other tools, cut, sort, uniq, and the rest, each of which has its own lesson. One difference from here: the mission shows no commands. You read the objective, recall the flag, and type it. That recall is what makes it stick.
Finish the other Text Processing lessons, then go find the line for real.
Practice grep in a real Linux terminal at The Linux Camp. Progress is verified automatically as you type commands on the machine.