grep Command in Linux with Examples (Search for a pattern in a file)

In this article, we will be learning how to use the grep command from within the Linux terminal.

In my previous article, I had explained How to use find command in Linux and I would request you to read that guide.

So grep stands for Global Regular Expression Print and it allows us to search for some text within files on our system and this is something that you will find yourself using all the time once you become comfortable with it.

Key features of grep command:

  • Search for Single or Multiple patterns
  • Search for text in multiple files at once
  • Force pattern to match only whole words
  • Display non-matching lines(Invert Match)
  • Ignore case distinctions
  • Print number of lines before and after the match
  • Recursive Search
  • Display only names of files with matches
  • Display only a count of selected lines per file
  • Filter Linux command output
  • GNU grep supports Regular Expressions
  • Display line number with output lines

First of all, let’s focus on some of the most important options that we can use with the grep.

OptionsExplanation
-P, --perl-regexpPattern is a Perl regular expression
-i, --ignore-caseIgnore case distinctions
-w, --word-regexpForce Pattern to match only whole words
-x, --line-regexpForce Pattern to match only whole lines
-n, --line-numberPrint line number with output lines
-o, --only-matchingShow only the part of a line matching Pattern
-r, --recursiveRecursive search
-R, --dereference-recursiveFollow all symlinks
-l, --files-with-matchesPrint only names of files with selected lines
-c, --countPrint only a count of selected lines per File
-B, --before-contextPrint number of lines before the match
-A, --after-contextPrint number of lines after the match
-C, --contextPrint number of lines before and after the match
-V, --versionCheck the GNU grep version
--helpHelp/Manual page access

So, let’s go ahead and look at some practical examples where you might use this.

You must follow the syntax given below to use the grep command.

grep [OPTION]... PATTERN [FILE]...

1. How to search file in Linux using the grep command

First of all, the most basic example is simply searching for some text within a normal file.

I am here in my terminal and in my current directory, there is a file named file.txt that has a bunch of random names and dummy data.

So let’s search this file using grep to see if it contains the text, Andrew.

If I run that then you can see it didn’t find any results. When there are no results it just jumps to the next line.

$ grep "Andrew" file.txt 
[email protected]:~/data$ 

Instead, let’s search for john and see if that has any results.

$ grep "John" file.txt 
John Abraham
Johnny Depp

And we can see that we got two results here where it found two lines containing john and return those entire lines.

Now the second line was johnny depp but it still found within this name.

So, it returned that anyway.

2. Search multiple Patterns using grep

You can search multiple patterns simultaneously.

Let’s take an example.

The following command will search these three patterns: linux, depp and, sahu.

$ grep -i 'linux\|depp\|sahu' file.txt 
Balamukunda Sahu
Ayush Sahu
Balamukunda Sahu 
Linux Administrator
Linux Operating System
Johnny Depp
johnny depp

3. Force Pattern to match only whole words

So now let’s say that we only wanted it to return a match if it was the whole word.

We only wanted to search for John and not return like Johnny depp.

So, to do this we can use the -w option.

$ grep -w "John" file.txt 
John Abraham

As you can see that it didn’t return Johnny Depp. It only returned the John Abraham.

Because we put in that we only wanted whole words.

4. Ignore case distinctions

Now I also added a lower-case version of that name in that file but it’s currently not returning that because grep is case sensitive.

So we can tell it to not be case sensitive by using the -i option.

$ grep -wi "john" file.txt 
John Abraham
john abraham

As you can see that now we get the lowercase version of that match and the regular case version of that match as well.

5. Print line number with output lines

Now just finding those matches doesn’t give us information other than knowing our text is actually there but sometimes you want some additional information.

For example, it’s common to want to know the line number of where it found our match, and to do this we can add the -n option to our search.

$ grep -win "john" file.txt 
1:John Abraham
3:john abraham

As you can see that now we’re getting some information about these matches.

It found a lowercase version on line 3 of that file and an uppercase version on line 1 of that file.

6. Print the number of lines before our match

Now another common bit of information that you might want is some additional context of where this match is found.

So we might want to also see a certain number of lines before and after the match to get an idea of the context of where this match was found.

And this is especially common if you’re searching for something in a computer program that you wrote and want to see the surrounding code of the match and there are several ways that we can do this.

So, if we want to see a certain number of lines that come before our match then we can use the uppercase -B option.

So I’m going to go ahead and pull up the last command that we just ran and now we want to add in this Uppercase -B option.

I’m doing this separate from the other options that we added in because we want to pass in an argument to this.

So, let’s just pass in a 3 which we’ll say that we want to see 3 lines before our match.

$ grep -w -B 3 "Johnny Depp" file.txt 
Balamukunda Sahu - Linux Administrator
Simanchal Patra
John Abraham
Johnny Depp

As you can see we got our match but now there’s some additional context here.

So we have 3 lines before our match here.

7. Print the number of lines after our match

Now if we want to see a certain number of lines after our match then we can use the Uppercase -A option.

$ grep -w -A 3 "Johnny Depp" file.txt 
Johnny Depp
john abraham
johnny depp
Shrikant Sahu

We can see that now instead of getting the lines before our match now we’re getting 3 lines after our match.

8. Print the number of lines before and after our match

And if you want to see the lines before and after your match then you can use the Uppercase -C option. This is also the one that I use most often as well.

$ grep -w -C 3 "Johnny Depp" file.txt 
Balamukunda Sahu - Linux Administrator
Simanchal Patra
John Abraham
Johnny Depp
john abraham
johnny depp
Shrikant Sahu

We can see that we got our match and there are 3 lines before the match and 3 lines after the match.

So, like I said I especially use this if I’m searching for some text in a computer program or a function or something that I want to see the context surrounding that match.

9. Search for text in multiple files at once

Okay so that is useful for finding texts in a certain file but what if we wanted to search for text in multiple files at once.

So, let’s say that we wanted to run the same search that we’ve been doing but against every file in our current directory.

Now you might think that we can just do something like this where instead of searching in a specific file that we could just pass in at the current directory as where we want to search.

But if we run that then we can see that we get this error that this our current directory is a directory.

$ grep -wi "linux" ./
grep: ./: Is a directory

So, what we need to do is use an asterisk(*) wildcard to say that we want everything in this directory.

So if I rerun that same command but put an asterisk(*) there and run that then we can see that this worked.

$ grep -wi "linux" ./*
./file2.txt:linux
./file2.txt:linux.com
./file2.txt:linux operating system
./file.txt:Balamukunda Sahu - Linux Administrator
grep: ./myfiles: Is a directory

You can see that it also tried to search in this subdirectory that we have in our current folder here.

So it couldn’t search that and we got an error there.

So maybe a better search for us there would be to just search all of the text files and we could do that by running the same command and instead just adding .txt after that wildcard.

$ grep -wi "linux" ./*.txt
./file2.txt:linux
./file2.txt:linux.com
./file2.txt:linux operating system
./file.txt:Balamukunda Sahu - Linux Administrator

If we run that then we can see that we got all of our matches but that it didn’t try to search this subdirectory here.

10. Recursive search using grep command

Okay, but maybe we wanted it to actually search that subdirectory and this is very common when working on large projects.

Maybe you have a lot of files and subdirectories and are searching for something that you can’t remember exactly what directory or file where it’s located.

So, in that case, you’d just want to search every single file and subdirectory in your project, and to do this we can use a recursive search with the -r option, and using a recursive search we actually can specify a directory as the starting point.

Let’s do a recursive search for our text within the current directory.

$ grep -wir "linux" ./
./file.txt:Balamukunda Sahu - Linux Administrator
./myfiles/content.txt:Balamukunda Sahu - Linux Administrator
./file2.txt:linux
./file2.txt:linux.com
./file2.txt:linux operating system

As you can see that we got those same results from within our current directory but it also searched the subdirectory and found some matches in this content.txt file.

Instead of that ./ you can just mention the . to get the same result.

$ grep -wir "linux" .
./file.txt:Balamukunda Sahu - Linux Administrator
./myfiles/content.txt:Balamukunda Sahu - Linux Administrator
./file2.txt:linux
./file2.txt:linux.com
./file2.txt:linux operating system

Using the -R option will follow all symbolic links.

$ grep -wirR "linux" ./
./file.txt:Balamukunda Sahu - Linux Administrator
./myfiles/content.txt:Balamukunda Sahu - Linux Administrator
./file2.txt:linux
./file2.txt:linux.com
./file2.txt:linux operating system
./backup:Balamukunda Sahu - Linux Administrator

Okay, so that’s nice that we were also able to search subdirectories and get the matches within there as well.

But you do want to be careful with recursive searches just because if you know if you’re in a big directory that has a ton of subdirectories then it’s going to try to search all of those and can take an extremely long time to return any results and if it takes too long you might just have to kill it.

So just be aware that those recursive searches could be searching through lots and lots of files.

11. Print only names of files with matches

Now if you’re searching through multiple files like this then you might not actually be interested in the matches themselves you might only be interested in seeing what files contain a match.

And if you only wanted that information then you can add on the -l option and only return the files with matches.

$ grep -wirl "linux" ./
./file.txt
./myfiles/content.txt
./file2.txt

As you can see that it doesn’t display the match it just comes up and says that we found a match in file.txt, file2.txt and all the matches within that subdirectory.

12. Print only a count of selected lines per file

Now if we wanted to see how many matches are in each file then we can use the -c option.

So, if we pull back up the command that we just ran and instead replace that -l with a -c.

$ grep -wirc "linux" ./
./file.txt:1
./myfiles/content.txt:1
./file2.txt:3

We can see that we get some similar output as the -l option but it also displays the number of matches in each file.

13. Filtering Linux command output using grep

Okay, so now let’s look at one practical use case for using grep that we haven’t covered yet.

We can pipe the output of other commands into grep to search for certain things.

For example, let’s say that we wanted to search our history for our latest sudo.

If we just display our history then we can see that if we wanted to find our sudo then there’s a lot of information here to shift through.

$ history | more
  288  tar -xvf myfiles.tar 
  289  ls
  290  rm fi*
  291  ls
  292  tar -xvf myfiles.tar fi*
  293  tar -xvf myfiles.tar --wildcards fi*
  294  ls
  295  rm fi*
  296  ls
--More--

Let’s pipe this in the grep to narrow it down a bit.

So, we can just run history as we did before but now we’re going to use a pipe(|) and pipe that into grep.

~$ history | grep "sudo"
  626  sudo mkdir /division/users
  627  sudo mkdir /division
  628  sudo mkdir /division/users
  629  sudo chmod 777 /division//users/
  636  sudo useradd -d /division/users/ user2
  641  sudo useradd -u 1100 user4
  644  sudo useradd -g 1011 user3
  646  sudo useradd -u 1011 -g 1011 user3
  647  sudo useradd -u 1005 -g 1005 user3
  649  sudo useradd -u 1005 -g 555 user3
  653  sudo useradd -g 1002 user3
  657  sudo userdel user4
  658  sudo userdel user3
  663  sudo useradd -u 1003 user3

As you can see that it narrows down our history to lines that match our grep search and we can even pipe this output into another grep command to narrow it down even further.

I just want to see the sudo command that I used for the useradd command then I could run that same last command with another pipe(|) and another grep.

So first it’s going to pass the output of history and narrow those down to the ones that have a “sudo” and then just going to take this output and pipe(|) that into grep again and search for the ones that have a useradd match.

$ history | grep "sudo" | grep "user3"
  644  sudo useradd -g 1011 user3
  646  sudo useradd -u 1011 -g 1011 user3
  647  sudo useradd -u 1005 -g 1005 user3
  649  sudo useradd -u 1005 -g 555 user3
  653  sudo useradd -g 1002 user3
  658  sudo userdel user3
  663  sudo useradd -u 1003 user3
 1016  sudo userdel user3

Now we only get our sudo‘s with the useradd commands.

Let’s take another example.

The following command will display by searching the user named helpdesk from the /etc/passwd file.

$ cat /etc/passwd | grep -i helpdesk
helpdesk:x:1000:1000:helpdesk,,,:/home/helpdesk:/bin/bash

14. Regular Expressions in Grep

Let’s see how we can do some more advanced searches using regular expressions.

grep uses POSIX regular expressions by default.

Example:1

Let’s say that we wanted to search a file for phone numbers. type the following command to do the same.

$ grep "...-...-...." file.txt 
000-000-0000
111-111-1111
222-222-2222
333-333-3333

As you can see that works and we got back the phone numbers from that file.

but let’s say that we wanted to make our search a little bit more specific and instead of searching for any character using the dot we wanted to search specifically for digits using backslash \d.

if we run this then we don’t get the results that we expect and that’s because grep isn’t using perl compatible regular expressions.

$ grep "\d{3}-\d{3}-\d{4}" file.txt

You can get this to work just by passing in the uppercase -P option here before the search.

$ grep -P "\d{3}-\d{3}-\d{4}" file.txt 
000-000-0000
111-111-1111
222-222-2222
333-333-3333

If I wanted to do a more advanced search and see what files contain phone numbers under my current directory then I could do something like this.

Example:2

Use the ^ (caret) symbol to match the expression at the start of a line. In the following example, the string linux will match only if it occurs at the very beginning of a line.

$ grep "^linux" file2.txt 
linux
linux.com
linux operating system

Example:3

Use the $ (dollar) symbol to match the expression at the end of a line. In the following example, the string sahu will match only if it occurs at the very end of a line.

$ grep -i "sahu$" file2.txt
Balamukunda Sahu
Ayush Sahu
Shrikant Sahu

Example:4

Use to match any single character enclosed in the brackets. For example, find the lines that contain “accept” or “accent“, you could use the following pattern:

$ grep "acce[np]t" file2.txt

Example:5

Use [^ ] to match any single character not enclosed in the brackets. The following pattern will match any combination of strings containing co(any_letter_except_l)a, such as coca, cobalt, and so on, but will not match the lines containing cola,

$ grep "co[^l]a" file2.txt

Source: linuxize.com

15. How to select non-matching lines(Invert Match)

To print, non-matching lines use the -v option with the grep command.

The following command will only display lines that do not contain strings called linux.

$ grep -vi "linux" file.txt 
Balamukunda Sahu
Ayush Sahu
Simanchal Patra
John Abraham
Johnny Depp

16. Show only the matched Pattern

The grep command normally prints the entire line of the matched string.

But if you just want to print the matched pattern use the -o option with the grep.

$ grep -oi "Sahu" file.txt 
Sahu
Sahu
Sahu
Sahu

17. Help/Manual page access

Use the following commands to access the Manual Page/Help Page of grep command.

$ man grep
$ grep --help

18. Check the GNU grep version

Type the following command to check the GNU grep version.

$ grep -V
grep (GNU grep) 3.1

You can visit at following websites to get more information on grep.

Conclusion

So that is How to essentially use grep command.

I hope that now you have a good understanding of how the grep command works and you have some ideas for how you can use this within your workflow.

If anyone does have any questions about what we covered in this guide then feel free to ask in the comment section below and I will do my best to answer those.

If you like our content, please consider buying us a coffee.

Buy Me A Coffee

We are thankful for your never ending support.

Leave a Comment