Grep is a small UNIX program for finding matching patterns. First released in V6 UNIX, you can now find it on almost any UNIX-like system such as Linux, macOS, and even BSDs. In this article, I will go through the basics of Grep and show you some examples of how to use the program for daily tasks.
Content
- The Basics of Using Grep
- Finding Files in a Directory
- Forget the Case
- Recursive Searches
- Matching Files Containing String
- Find the Opposite
- Words and Lines
- Adding Line Numbers to the Grep Output
- Using Extended Regex with Grep
- Adding Adjacent Lines to the Grep Output
The Basics of Using Grep
At its core, Grep is a simple and straightforward program. It takes in an input, finds the text that you want in that input, and prints the matches as output. Grep can process just about any plain text source. This allows it to read input coming from other commands and look through files directly.
The simplest way to get started with Grep is by reading data from a text file. For example, the following command prints the content of my sample.txt file:
grep '' sample.txt
Further, you can use this feature to search and find specific pieces of text inside your text files:
grep 'word' sample.txt
You can also use Grep with UNIX pipes, allowing you to glue together multiple programs in a single command:
cat sample.txt | grep ''
Good to know: looking to expand your UNIX knowledge? Learn how to screen pagers work in Linux by checking out our cheatsheet for GNU less.
Finding Files in a Directory
One of the easiest tasks that you can do with Grep is finding files in a directory listing. To do this, you can send the output of the ls
command through a UNIX pipe straight to Grep.
The following command will print and highlight all the files in your Downloads folder with the .jpg file extension:
ls ~/Downloads | grep \\.jpg
You can also send a more elaborate ls
output to Grep and use that for pattern matching. For instance, the following lists all the files in the directory with less than 1MB of file size:
ls -lh ./ | grep .K
Forget the Case
By default, almost all programs in a UNIX-like system are case-sensitive. This means that the system treats the string “Hello” differently from “hello,” “hEllo,” and “helLo.”
This behavior can be a pain when looking for strings inside files. For example, an essay can have both “Hello” and “hello” at the same time. To address this, run Grep with the -i
flag followed by the string that you want to find.
grep -i Hello hello.txt
Recursive Searches
Grep can search through more than one file or directory at the same time. This is useful if you’re working on a project with multiple files and you want to know where a string of text appears in a directory. For example, the following command matches the word “MakeTechEasier” inside the “sample” directory:
grep -r 'MakeTechEasier' ./sample
That said, using the -r
flag will also prompt Grep to look through every file in your target directory. This can be an issue if you also have non-text files inside the folder that you’re searching on. To prevent that, run Grep with the -I
flag:
grep -rI 'MakeTechEasier' ./sample
On a side note: learn how you can create files in the terminal using the touch command.
Matching Files Containing String
Apart from showing where a specific string occurs in different files, you can also use Grep to create a list of files that contain your target text. This is useful if you want to know if a file contains a particular string but don’t want Grep to print every instance of it in the terminal.
To do this, run Grep with the -r
and -l
flags followed by the string that you want to match and the directory that you want to look at:
grep -rl MakeTechEasier ./sample
You can even enclose your Grep command inside a Bash subshell to create multiple conditions for your text matching. For example, the following line of code will only return that files that contain both “Hello” and “MakeTechEasier” in the “sample” folder:
grep -rl MakeTechEasier $(grep -rl Hello ./sample)
Find the Opposite
Aside from doing direct searches, Grep can also return the results that doesn’t match your initial criteria. While it might seem counterintuitive at first, this can be helpful in cases where you need to highlight errors and anomalies from your text input.
To do this, run Grep with -v
along with the other flags that you want to enable. For instance, the following will recursively search through every file in my “/etc/nginx” folder and return all the lines that don’t contain the string “nginx”:
grep -rv 'nginx' /etc/nginx
Words and Lines
It also might be useful to tell Grep to search for complete words or lines, instead of anything containing a certain pattern. This is useful if you’re matching a string of characters that’s common in a lot of words. For example, matching the word “it” will return a ton of false positives since “it” is a common string that you can find in words.
To fix this, you can run Grep with the -w
flag followed by the word that you want to match:
cat it.txt | grep -w it
Instead of printing out every word that contains the pattern, Grep will only print the word by itself. It does the same thing for entire lines with the -x
flag, so if you’re looking for a phrase or a single line in a configuration file, that can really help.
Adding Line Numbers to the Grep Output
Line numbers are an important part of debugging programs and proofreading text. It allows you to accurately reference the location of a specific function or sentence, making it a lot quicker to fix and amend.
In this regard, Grep comes with the ability to print line numbers to its default output. To do this, run the program with the -n
flag followed by the string that you want to match:
grep -n main ./my-code.c
With the help of UNIX pipes, you can also modify Grep’s output and only print the line numbers of what you’re looking for. This makes it a lot cleaner and easier to parse large texts:
grep -n Sed essay.txt | cut -f 1 -d :
FYI: UNIX pipes are more than just a tool for Grep. Learn how to automate your remote shell tasks by creating and using SSH pipes.
Using Extended Regex with Grep
Grep uses the Basic Regular Expression (BRE) metacharacter set to match and filter text strings. While this usually works for most tasks, some users might find it limiting, especially when working with pattern groups.
To address this, most Grep implementations provide the -E
flag, which allows the program to parse Extended Regular Expression (ERE) metacharacters. For instance, the following command will only work with the -E
flag:
printf "hello\nhellooooo\n" | grep -E .*o{2}$
Note: the GNU version of Grep uses some ERE functionality by default. However, it’s good practice to use -E
whenever you use ERE to preserve compatibility with other UNIX-like systems.
Further, Grep also has a special mode that drops all Regex functions altogether. To use this, run the program with the -F
flag followed by your plain string:
grep -F [MakeTechEasier] ./fixed.txt
Adding Adjacent Lines to the Grep Output
One of the core strengths of Grep is showing where text appears in your file or input stream. However, there are instances where just knowing the exact location of a string doesn’t help when troubleshooting issues. For example, a crash log usually provides additional context before it prints the traditional “Segmentation Fault” message.
One way to solve this issue is by running Grep with the -C
flag followed by the amount of lines that you want to print around your target text. The following command prints five lines before and after your text match:
grep -C 5 'Hello' ./hello-sample.txt
You can also customize whether Grep only prints the pre-match or post-match contexts with the -B
and -A
flags. For instance, the following will print the previous ten lines after your target string:
grep -A 10 'Hello' ./hello-sample.txt
With the basics of Grep and how to use it for your daily tasks under your belt, you can now take your first step in understanding the command line and core UNIX utilities. Explore more of this very diverse and deep world by learning how sed works in Linux.
Image credit: Alejandro Escamilla via Unsplash. All alterations and screenshots by Ramces Red.
Ramces Red –
Staff Writer
Ramces is a technology writer that lived with computers all his life. A prolific reader and a student of Anthropology, he is an eccentric character that writes articles about Linux and anything *nix.
Subscribe to our newsletter!
Our latest tutorials delivered straight to your inbox
Sign up for all newsletters.
By signing up, you agree to our Privacy Policy and European users agree to the data transfer policy. We will not share your data and you can unsubscribe at any time. Subscribe