I was talking to a few of my colleagues today at work and they were not aware that there are different type of grep commands under Linux, such as grep
, fgrep
, egrep
and pgrep
, therefore I thought that it would be a nice idea to write this article explaining what each of them does.
grep
- even though one may assume that it's just a funny spelling of 'grab' - that is - grab "pattern" from my file - stands for 'Global Regular Expression Print' and it allows you to scan the content of a file - passed in as an argument - and return results that match your pattern. grep
accepts lots of parameters and I will mention the few that I use later on.
Let's assume that we have a file that contains the following:
cat test.txt
Auto-creation of a test room that can have one table
Auto-creation of a test table that can have 2 players
Players need to enter their names to join a table
Basic gameplay is fully implemented but additional rules are missing
If the pack of cards get emptied, the discard pile is reshuffled and will become the new pack
Messages are passed in between the connected clients to indicated end of turn events
Enter the gameplay
grep "enter" test.txt
#returns: Players need to enter their names to join a table
Notice that we didn't get the last line as a match because grep
does case-sensitive pattern matching by default. One way to get around this is to use the -i
flag:
grep -i "enter" test.txt
#returns:
#Players need to enter their names to join a table
#Enter the gameplay
What if you'd like to search through the file and find the words 'enter' as well as 'gameplay' (an or condition) but you want to do this in one run? This time, you'd have to use egrep
- Extended Global Regular Expressions Print - that allows you to add regexes as expressions which also means that while you can simply find special, meta-characters with grep
inside your file (such as |, ?, (, ), +), using egrep
will transform these into regular expression meta-characters. (If you want to find the pipe symbol in your file for example, you'd have to escape it using backslash: |
, otherwise it will be translated as an or operator.
egrep -i "enter|gameplay" test.txt
#returns:
#Players need to enter their names to join a table
#Basic gameplay is fully implemented but additional rules are missing
#Enter the gameplay
(An alternative would be to run grep -E
)
This particular "grep" is not really comparable to the others as it is looking through running processes to find a process ID of an application (henceforth pgrep stands for Process ID Global Regular Expression Print).
An example usecase would be: pgrep httpd
which would return the process ID of the Apache webserver.
Last but not least, fgrep, usually referred to as 'fast grep' - officially called as 'Fixed string Global Regular Expression Print' (equivalent of grep -F
) does not recognise any regex specific meta-characters, so the search that it executes in the file returns faster. The use-case for fgrep
would be in a situation where you are looking for a character in your file - which also happens to be a regex meta-character. For example grep "." test.txt
would return every single line from the file, however fgrep "." text.txt
would only return the lines where there is an actual dot character.
The two other flags other than -i
that I usually use are -aX
and -bY
- where X and Y are both integers - that allows you to print the X amount of lines after and Y amount of lines before your pattern matched line. For example:
grep "fully" -a1 -b1 test.txt
#returns:
#Players need to enter their names to join a table
#Basic gameplay is fully implemented but additional rules are missing
#Enter the gameplay
The other flag that I also tend to use is -v
which emits particular lines from a resultset. Let's assume that every second line in test.txt
would be a -1 - maybe another application needs this to add line breaks (I know, it's silly but this is just an assumption for the time being). Therefore, to exclude those from your result you'd do:
grep "fully" test.txt | grep -v "\-1"
#returns:
#Basic gameplay is fully implemented but additional rules are missing
#Don't forget we have -1s all over the place in our test.txt now!
Note that we had to escape the -
symbol, otherwise grep would take that as a meta-character and that would fail.