Pattern Matching using grep, egrep, and fgrep

grep is the command that searches text for a pattern and prints the matching lines: plain grep uses basic regex, egrep (grep -E) uses extended regex, and fgrep (grep -F) matches a fixed literal string fast, and together they are how you search the logs.

11 min read · 7 cards · 2 checks

Read in: English · हिन्दी · ગુજરાતી


Theory

Searching the logs

The campus server's log file has thousands of lines, and you need the ones that say ERROR. Scrolling by hand is hopeless. This is the everyday job of grep: give it a pattern and a file, and it prints every line that matches.

grep is one of the most-used commands in all of Linux, and it comes in three flavours, grep, egrep, and fgrep, that differ in how they interpret your pattern. This lesson shows all three and the handful of flags that make grep genuinely powerful.

At a glance

CommandHow it reads the pattern
grepBasic regular expressions (the default)
egrep (grep -E)Extended regular expressions: |, +, ?, ( ) without escaping
fgrep (grep -F)A fixed literal string: no regex, special characters match themselves
-iFlag: case-insensitive matching
-c / -nFlag: count matching lines / show line numbers
-vFlag: invert, show lines that do NOT match

Practical

grep searching a log (verified)

$ grep "ERROR" log.txt          # lines containing ERROR
ERROR disk full
ERROR timeout
$ grep -c "ERROR" log.txt       # count them instead
2
$ grep -i "info" log.txt        # case-insensitive: INFO and info
INFO started
info lowercase
$ grep -E "ERROR|WARN" log.txt  # extended: ERROR or WARN
ERROR disk full
ERROR timeout
WARN low memory

Formula

Pick the variant to match your pattern

Choose by what your pattern needs. Use plain grep for a simple pattern or basic regex. Use egrep (or grep -E) when your pattern uses extended features like | (or), +, or grouping, so you can write them without backslashes. Use fgrep (or grep -F) when you want to match a literal string exactly, treating characters like . and * as themselves, not as regex.

And remember the flags: -i ignores case, -c counts, -n numbers the lines, -v shows what does NOT match. These turn grep from a finder into a precise investigative tool.

Quiz

You want to count how many lines in log.txt contain the word ERROR, case-sensitively. Which command is best?

  1. grep -v "ERROR" log.txt, which counts matches
  2. grep -c "ERROR" log.txt, which prints the number of matching lines
  3. grep -i "ERROR" log.txt, which counts matches
  4. fgrep counts automatically without a flag
Show the answer

grep -c "ERROR" log.txt, which prints the number of matching lines

grep -c prints the COUNT of matching lines, so grep -c "ERROR" log.txt gives the number directly (here, 2). Option A uses -v, which INVERTS the match, it would show or count the lines WITHOUT ERROR, the opposite of what you want. Option C uses -i (case-insensitive) and, more importantly, does not count, it prints the matching lines themselves; -i would also match 'error' in lowercase, breaking the 'case-sensitive' requirement. Option D is wrong: no grep variant counts without the -c flag. Match the flag to the task: -c to count, -i for case-insensitive, -v to invert, -n for line numbers.

Think first

Why does fgrep exist if grep can already search?

grep handles patterns, so why have fgrep for fixed strings? What does 'fixed' buy you? Then tap.

Show the answer

fgrep (grep -F) treats your pattern as a LITERAL string, which is both SAFER for special characters and FASTER. The safety point: regex characters like . * [ ] ^ $ have special meaning in normal grep, so searching for a real dotted string like an IP address '192.168.1.1' with plain grep would let each . match ANY character, giving false matches. With fgrep, those characters are taken literally, so 'a.b' matches only a real 'a.b', not 'aXb'. That is exactly why you reach for fgrep when your search text contains regex metacharacters you want treated as ordinary text (file paths, IP addresses, code snippets). The speed point: because fgrep does not have to interpret a regular expression, just find a fixed string, it can be faster, which matters when scanning very large files. So fgrep is the right tool when you know your target is an exact literal string: you avoid accidental regex surprises and get a quick, predictable search. If your text has dots, brackets, or asterisks that you mean literally, fgrep saves you from escaping every one of them. Literal and fast: that is fgrep's niche.

Summary

Key takeaways

  • grep searches text for a pattern and prints the matching lines, the everyday way to search logs and files.
  • grep uses basic regex; egrep (grep -E) uses extended regex (|, +, ?, grouping without escaping).
  • fgrep (grep -F) matches a fixed literal string: special characters are taken literally, and it is fast.
  • Key flags: -i case-insensitive, -c count matching lines, -n show line numbers, -v invert (non-matching), -r recursive.
  • grep -c "ERROR" counts matching lines; grep -i matches regardless of case; grep -v shows what does not match.
  • Use fgrep for literal text containing regex characters (paths, IPs) to avoid accidental matches.
  • Memory hook: grep basic, egrep extended, fgrep fixed; -i -c -n -v are the everyday flags.

Study this properly

This page is the lesson to read. In Gri-Learn the same topic is a graded deck: the self-checks are scored and your weak topics are tracked. Free to start.

Start this topic

Already have an account? Sign in

More from Advanced Text Processing Tools

Gri-Learn · syllabus-mapped B.C.A. lessons in English, Hindi and Gujarati

Pattern Matching using grep, egrep, and fgrep · Linux Operating System (LOS) (Minor-04) · Gri-Learn