grep

Linux grep Command

Grep is one of the handiest tools you can have at your disposal. This command-line utility performs a search in plain-text data sets. Grep is actually an acronym for “globally search a regular expression and print”. Grep started its journey as a part of the UNIX family. Over time, it’s now available to all the popular platforms like Linux, Mac, BSD, and even Windows!

Have you used grep before? Most of the time, the basic grep trick can do most of the work. However, grep offers tons of ways to perform the search and fine-tune the output to a more usable version. In this article, let’s check out the usage of grep command.

Grep usage

Verifying existence

If you’re running any sort of Linux distro, then you already have grep installed. Run the following command in the terminal.

grep --version

This command is used to show the version of currently installed grep. Now, we need a demo file. In my case, I’ll be generating a text file that includes all the installed packages on my system.

Basics

The basic usage of grep follows the following structure.

grep <options> <pattern> <file>

Or, for easier understanding, use this one.

grep <options> -e <pattern> -f <file>

In this case, grep will perform a search in the file and print all the lines that include the pattern (search term).

grep python ~/Desktop/PackageList.txt

Grep searched the file “PackageList.txt” I generated earlier and printed all the lines that include “python”.

This same operation can be performed in another way. Check out the following example.

cat ~/Desktop/PackageList.txt | grep python

Here, using “cat” command, I sent the content of the file “PackageList.txt” to grep. Using the output of cat, grep performed the search and printed the lines that contain the search term.

Now comes a fun thing. You can literally stack multiple grep commands just like that.

cat ~/Desktop/PackageList.txt | grep - | grep p | grep python

The first grep filters down to the lines with a hyphen, the second filter down to the lines with p, and the final grep filters down to the lines with python. Makes sense?

Case sensitivity

When performing a search, case sensitivity is a major question. By default, grep is case sensitive.

For example, searching for “Python” won’t show any result.

cat ~/Desktop/PackageList.txt | grep Python

To make grep case “insensitive”, add the following option.

cat ~/Desktop/PackageList.txt | grep -i Python

File search

Let’s say that you have a directory with numerous text files. Your goal is to identify the file(s) that contain or doesn’t contain a pattern (search term).

I find this method quite helpful when searching within a pile of log files. As I don’t have the time to open and check every single file manually, I have grep to do the job for me.

For listing files containing the match, use the “-l” flag.

grep -l <pattern> /search/directory/*

As the result suggests, the term “python” is present in all 3 files present in the “Desktop” directory.

For listing files without any match, use the “-L” flag.

grep -L <pattern> /search/directory/*

“NoMatch.txt” is the only file that doesn’t contain the term “python”.

Inverted search

The default behavior of grep is to print only the lines with the matching pattern, right? It’s time to reverse the process. This time, we’ll be printing only the lines WITHOUT the matching pattern.

Just pass the “-v” option to grep.

cat ~/Desktop/PackageList.txt | grep -i -v Python

Printing lines before/after the match

By default, grep will only print the line that matches the search pattern. Using this technique, you can tell grep to print lines before/after the match as well.

For printing lines before the match, use the following structure.

grep -B<line_number> <pattern> <file>

Here, 5 is the line of number that grep will print BEFORE the matching line.

For printing lines after the match, use the following one.

grep -A<line_number> <pattern> <file>

How about printing both before and after the matching line? In that case, use “-C” flag.

grep -C<line_number> <pattern> <file>

Line number

When grep shows the output, it doesn’t mention the line number. For the associated line number(s), use “-n” flag.

grep -n <pattern> <file>

Single word

If the flag “-w” is used, grep will treat the pattern as a whole word.

grep -w <pattern> <file>

Limiting grep search

Grep allows specifying the number of lines to search in the file. This method is useful if you’re dealing with a big file (like system log). Use the flag “-m”.

grep -m <line_number> <pattern> <file>

Recursive search

It’s one of the most helpful features grep offers for heavy usage. Grep can recursively search a directory and find all the matches from all the files it faces.

grep -R <pattern> <directory>

Or,

grep -r <pattern> <directory>

I often find using this recursive function along with “-l” flag.

Quiet mode

Grep can be run in “quiet” mode. When running in “quiet” mode, grep won’t print any output to the terminal. Instead, it will return 0 (at least, a match was found) or 1 (no match found).

grep -q <pattern> <file>
echo $?

Regex

Grep also allows regex (regular expression) searches. This adds a whole new level of complexity and usability of grep as a searching tool.

For example, you can use brackets to search for both “too” and “two” at the same time.

cat ~/Desktop/gpl-3.0.txt | grep t[wo]o

This next example will only print the line if the match occurs at the very beginning of the line.

grep ^GNU ~/Desktop/gpl-3.0.txt

As for matching the ending, use this one.

grep you$ ~/Desktop/gpl-3.0.txt

If you want to use Perl regex, then use the “-P” flag. It will treat the pattern as Perl regex.

grep -P <pattern> <file>

Final thoughts

Grep offers tons of ways to customize the search function. The availability of regex unlocks a whole new horizon for potential usage of grep. The cool thing is, you can use both general and Perl regex; whichever you feel comfortable with.

For the most detailed explanation, always consult the man page.

man grep

Cheers!

About the author

Sidratul Muntaha

Sidratul Muntaha

Student of CSE. I love Linux and playing with tech and gadgets. I use both Ubuntu and Linux Mint.