The tool grep is a fantastic CLI (Command-Line Interface) allowing you to filter any pattern for a given input, including a file.

To know if you have GNU grep, you can run in your terminal grep --version. If you don’t have GNU grep, I would recommend installing it.

This article is a summary of the following video I made. I would recommend you to watch it first, it’s more complete with many examples and exercises:

If you find the videos I have on this channel helpful, don’t hesitate to subscribe and to like them. It would then appear to other Youtubers to help even more!

I also recommend you to:

  1. Download these files
  2. Fire up your beautiful shell
  3. Try each command you’ll see in this article

You won’t learn much if you only read (or watch a video) passively.

In this article we’ll see together how to:

  • Colorize grep output
  • Case insensitive patters
  • Output lines with pattern matched
  • Output lines with pattern not matched
  • Output only the pattern matched
  • Output lines numbers
  • Output the match count
  • Hiding filenames
  • Always output filenames
  • Only output filenames
  • Only output filenames without matches
  • Output lines after the match
  • Output lines before the match
  • Output lines before and after the match
  • Excluding files
  • Piping grep
  • Summary: a mindmap of grep
  • Using grep in practice

Colors!

I would advise you to colorize the output of grep using the option --color as following:

grep --color=auto

But it’s a pain to use this option each time you use grep. You can define an alias to make grep always colorful:

alias grep="grep --color=auto"

It’s now a firework machine.

Output Lines With Pattern Matched

Here’s the general way to use grep:

grep "<pattern>" <input>

The <pattern> is a regular expression and the <input> can be what you enter in your terminal or a file. For example:

grep "package" pacman.log

You’ll see this output:

Displaying lines with pattern matched

You can see that the pattern package is part of these two lines; that’s why they are output. Incredible! It would be nice if we could do that in our daily life. I already know what words I would filter.

Note that the pattern wouldn’t be colorized without the option --color set to auto as we saw above.

Output Lines With Pattern Not Matched

If you want to invert the match, that is, only output the lines which don’t match the pattern, you can use the option -v as follows:

grep -v "package" pacman.log

This time, you’ll output all the file except the two lines containing the pattern package.

Output Only The Pattern Matched

It can be useful to only output the match and not the whole line. You can do that with the option -o

grep -o "package" pacman.log

Output Line Numbers

If you to output the lines and the line numbers, you need to use the option -n. For example:

grep -n "package" pacman.log

The line numbers will be prefixed to each line of the output.

Only Output Match Count

You can also only output the match count with the option -c:

grep -c "package" pacman.log

Case Insensitive Patterns

By default, to match a pattern, you’ll need to know what letters of the pattern are uppercase or lowercase. You can match your pattern without worrying about the case if you use the option -i:

grep -i "pacman" '*.log'

You can see that grep can filter more than one file. The glob * has a special meaning: it represents 0 or more character. Said differently, we want every file in our working directory ending up with .log. The following is equivalent:

grep -i "pacman" haskell.log pacman.log

Filenames

Hiding Filenames

As you saw, grep will output the filenames of the occurrence matches if you use more than one file as input. To hide them, you can use the option -h. An example:

grep -h "package" '*.log'

Always Output Filenames

If you want to output the filename where there’s a match, even if you gave only one file as input, you can use the option -H. As usual, here’s an example you can run in your terminal:

grep -H "package" pacman.log

For some option, the uppercase variant will do the inverse of the lowercase one, like -h and -H.

Only Output Filenames

To only output the filenames where the patterns match, you can use the option -l:

grep -l "package" '*.log'

Only Output Filenames Without Matches

You might have guessed it: the option -L only output the filename where the pattern doesn’t match:

grep -L "package" '*.log'

Output Lines Around The Match

Outputing the lines before or after your match can be useful to get a bit of context and understand the result of your filtering.

Output Lines After The Match

To output a variable number of lines After the line with a match, you can use the option -A:

grep -A 3 "package" pacman.log

Output Lines Before The Match

Similarly, if you want to output the lines Before the match, you can use the option -B:

grep -B 3 "package" pacman.log

Output Lines Before And After the Match

You can even output some lines before and after the match with the option -C:

grep -C 3 "package" pacman.log

In this example, the second match of package won’t output the 3 lines after because it’s the end of the file after the line containing the match.

Did you see the pattern? After, Before, Context: it’s ABC!

Excluding Files

We always gave the files we wanted to filter to grep’s input, but what if we want everything except a couple of files? For that, we can use the option --exclude:

grep "package" --exclude="pacman.log" '*.log'

Piping grep

You can directly give the output of a command to the input of grep if you want to filter it. Actually, you can do that with every CLI accepting an input using pipes.

For example, if I run ps (a CLI to output the processes running on my machine), I get this:

    PID TTY          TIME CMD
   2026 pts/9    00:11:36 nvim
   2431 pts/11   00:01:11 hugo
   2584 pts/10   00:00:01 tmuxp
   3009 pts/18   00:00:01 nvim
   3241 pts/20   00:00:17 taskell
   3484 pts/22   00:00:11 taskell
   3663 pts/21   00:00:00 nvim

What if I want only the lines containing the pattern nvim? I can do the following:

ps -a | grep "nvim"

It means that I give to the input of grep the output of the command ps -a. Here’s the result:

   2026 pts/9    00:11:36 nvim
   3009 pts/18   00:00:01 nvim
   3663 pts/21   00:00:00 nvim

Pipes are one of the reason why the command line is so powerful: you can pipe small CLIs doing one thing and you’ll have crazy results!

In a Nutshell: a Mindmap of grep

mindmap of grep

Using grep in Practice

It’s nice to learn all of that, but how can you use grep in real life? Here’s a video showing you a problem I had and I solved nicely using grep and other CLIs: