Cheatsheets

Grep

Grep

Complete grep reference with pattern matching, regular expressions, flags, context options, and practical examples for searching text files

7 Categories 24 Sections 48 Examples
Grep Search Pattern Matching Regular Expressions Regex Linux

Getting Started

Introduction to grep and basic concepts

What is Grep

Understanding grep and its use cases for text searching

Grep overview and basic usage

Grep searches for lines containing the pattern "ap" regardless of position in the line.

Code
Terminal window
# Grep stands for: global regular expression print
# It searches for lines matching a pattern in files
# Basic syntax: grep [OPTIONS] PATTERN [FILE...]
# Prints lines that match the pattern
# Key features:
# - Search multiple files
# - Use regular expressions for powerful patterns
# - Filter and display specific lines
# - Count matches
# - Case-insensitive search
# - Show context around matches
Execution
Terminal window
echo -e "apple\nbanana\ncherry\napricot" | grep "ap"
Output
Terminal window
apple
apricot
  • Grep is case-sensitive by default
  • Pattern can be literal text or regular expression
  • Matches any line containing the pattern (substring match)
  • Returns nothing if no matches found

Grep vs other text processing tools

Grep excels at simple pattern matching and filtering. The ^ anchor matches line start, filtering only error lines.

Code
Terminal window
# Compare grep with similar tools:
# grep: Search for patterns in lines (filtering)
# sed: Stream editor for text transformations
# awk: Full text processing language with patterns
# find: Search for files by name or properties
# Use grep when you need:
# - Quick pattern matching in text
# - Filter lines based on conditions
# - Search in multiple files
# - Use regular expressions for search
Execution
Terminal window
echo -e "error: connection failed\ninfo: starting\nerror: timeout" | grep "^error"
Output
Terminal window
error: connection failed
error: timeout
  • Grep is best for pattern filtering tasks
  • More efficient than awk for simple searches
  • Easier than sed for match-based filtering
  • Can pipe to other commands for complex workflows

Installation and Setup

Installing grep and verifying functionality

Verify grep installation

Grep is typically pre-installed on Linux and Unix systems. Display version and confirm functionality.

Code
Terminal window
# Check if grep is installed
which grep
# Display grep version
grep --version
# Show grep help
grep --help | head -20
Execution
Terminal window
grep --version
Output
Terminal window
grep (GNU grep) 3.7
Copyright (C) 2021 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later.
  • Grep is usually included by default on Linux systems
  • Different implementations: GNU grep, BSD grep
  • GNU grep typically more feature-rich
  • Version may vary across systems

Install grep on different systems

Installation of grep across different Linux distributions and macOS systems.

Code
Terminal window
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install -y grep
# CentOS/RHEL
sudo yum install -y grep
# macOS (BSD grep is default)
brew install grep # Installs GNU grep as ggrep
# Alpine Linux
apk add grep
# Arch Linux
sudo pacman -S grep
Execution
Terminal window
which grep && grep --version | head -1
Output
Terminal window
/usr/bin/grep
grep (GNU grep) 3.7
  • GNU grep is most feature-complete version
  • macOS comes with BSD grep; install GNU grep with Homebrew
  • Always available on standard Linux deployments
  • Some advanced flags may not work on BSD grep

Basic Pattern Matching

Simple text search and basic pattern techniques

Whole Word Matching

Match complete words without partial matches

Match whole words with -w flag

The -w flag matches only "cat" as a complete word, excluding "concatenate" which contains "cat" as part of a larger word.

Code
Terminal window
# -w flag matches only complete words
grep -w "word" filename
# Avoids partial matches
# "word" matches: word, the word is
# "word" does NOT match: sword, wording, foreword
grep -w "cat" pets.txt # only standalone "cat"
grep -w "test" code.py # only "test" word, not in "testing"
Execution
Terminal window
echo -e "the cat sat\nconcatenate strings\ncat is here" | grep -w "cat"
Output
Terminal window
the cat sat
cat is here
  • -w stands for --word-regexp
  • Matches word boundaries (space, punctuation, start/end)
  • Useful for searching code to avoid partial matches
  • Works with regular expressions too

Whole word search ignoring case

Combining -i and -w provides case-insensitive whole word matching.

Code
Terminal window
# Combine -w with -i for case-insensitive word matching
grep -iw "The" text.txt
# Searches for complete words ignoring case
grep -iw "error" log.txt # matches: error, Error, ERROR
grep -iw "function" code.js # matches complete word "function"
Execution
Terminal window
echo -e "The quick brown fox\nthe lazy dog\nThey will go" | grep -iw "the"
Output
Terminal window
The quick brown fox
the lazy dog
  • -iw combines ignore-case and word-regexp
  • More flexible searching for code and logs
  • Avoids false positives from partial matches

Whole Line Matching

Match patterns that span entire lines

Match exact lines with -x flag

The -x flag only matches lines containing exactly "test" with nothing else.

Code
Terminal window
# -x flag matches entire line only
grep -x "exact line" filename
# Pattern must match complete line (not substring)
# "test" matches: test (exact match)
# "test" does NOT match: test123, mytest, testing
grep -x "TRUE" config.txt
grep -x "done" status.log
Execution
Terminal window
echo -e "test\ntest123\nmy test\nonlytest" | grep -x "test"
Output
Terminal window
test
  • -x stands for --line-regexp
  • Useful for matching configuration file values
  • Equivalent to anchoring pattern with ^...$
  • Strict matching without partial line matches

Exact line matching with regex patterns

-x requires the pattern to match the complete line. The pattern matches exactly 3 digits.

Code
Terminal window
# Use -x with regex for exact line patterns
grep -x "status:.*" config.txt
# Match specific line format
grep -x "[0-9]\{3\}" numbers.txt # exactly 3 digits
grep -xE "^[a-z]+$" words.txt # lowercase letters only
Execution
Terminal window
echo -e "123\n12\n1234\n12a" | grep -x "[0-9][0-9][0-9]"
Output
Terminal window
123
  • -x requires complete line match including spaces
  • Combine with -E for extended regex
  • Useful for structured data validation

Multiple Patterns

Search for multiple patterns using different methods

Match multiple patterns with -e flag

The -e flag allows matching multiple patterns. Lines matching any pattern are included.

Code
Terminal window
# Use -e for each pattern (OR logic)
grep -e "pattern1" -e "pattern2" filename
# Matches lines with pattern1 OR pattern2
grep -e "error" -e "warning" log.txt
grep -e "TODO" -e "FIXME" code.py
# Can use multiple -e flags
grep -e "info" -e "debug" -e "error" app.log
Execution
Terminal window
echo -e "error: failed\nwarning: deprecated\ninfo: started\nerror: retry" | grep -e "error" -e "warning"
Output
Terminal window
error: failed
warning: deprecated
error: retry
  • Each -e adds another pattern to match (OR logic)
  • Returns lines matching any pattern
  • Useful for filtering multiple categories
  • Can combine with other flags like -i or -c

Alternation with extended regex

The -E flag enables extended regex with | for alternation, matching any alternative.

Code
Terminal window
# Use pipe | for alternation with -E flag
grep -E "pattern1|pattern2" filename
# Single pattern but with alternatives
grep -E "error|warning" log.txt
grep -E "\.js|\.ts" files.txt
# More complex patterns
grep -E "(fruit|vegetable)" grocery.txt
Execution
Terminal window
echo -e "apple fruit\nbroccoli vegetable\nstrawberry fruit\ncarrot vegetable" | grep -E "fruit|vegetable"
Output
Terminal window
apple fruit
broccoli vegetable
strawberry fruit
carrot vegetable
  • -E enables extended regular expressions
  • Pipe | provides cleaner syntax for multiple patterns
  • Works with groups: (pattern1|pattern2)
  • More flexible than multiple -e flags

Regular Expressions

Advanced pattern matching using regular expressions

Basic Regular Expressions

Basic regex patterns and syntax

Basic regex metacharacters

The ^ anchor matches only lines starting with "error". The $ would match lines ending with a pattern.

Code
Terminal window
# Basic regex characters (BRE - Basic Regular Expressions)
# . = any character
# * = zero or more of previous
# ^ = start of line
# $ = end of line
# [abc] = any of a, b, c
# [^abc] = not a, b, or c
grep "^error" log.txt # lines starting with error
grep "\.py$" files.txt # lines ending with .py
grep "^[0-9]" data.txt # lines starting with digit
Execution
Terminal window
echo -e "error: failed\nwarning: check\nerror: retry\ninfo: started" | grep "^error"
Output
Terminal window
error: failed
error: retry
  • Grep uses Basic Regular Expressions (BRE) by default
  • In BRE, some characters need backslash escaping
  • ^ and $ are line anchors, not in pattern
  • . matches any single character except newline

Character classes and ranges

The pattern "test[0-9]" matches "test" followed by any single digit.

Code
Terminal window
# Character classes [] match any character in the set
grep "[0-9]" file.txt # any digit
grep "[a-z]" file.txt # any lowercase letter
grep "[A-Z]" file.txt # any uppercase letter
grep "[a-zA-Z]" file.txt # any letter
grep "[^0-9]" file.txt # NOT a digit
# Common patterns
grep "[aeiou]" words.txt # contains vowel
grep "test[0-9]" results.txt # test followed by digit
Execution
Terminal window
echo -e "test1\ntest2a\nrandom\ntest" | grep "test[0-9]"
Output
Terminal window
test1
test2a
  • [0-9] is equivalent to \d in other regex flavors
  • [^...] negates the character class
  • Ranges use hyphen: [a-z] for lowercase letters
  • Order doesn't matter in character class

Extended Regular Expressions

Enhanced regex syntax with -E flag

Extended regex patterns with -E

The -E flag enables extended regex. The + means one or more, matching test followed by one or more digits.

Code
Terminal window
# Extended Regular Expressions (ERE) with -E flag
# + = one or more
# ? = zero or one
# () = grouping
# | = alternation
# {} = repetition count
grep -E "error+" log.txt # error, errorr, errorrr
grep -E "test[0-9]+" file.txt # test followed by 1+ digits
grep -E "colou?r" text.txt # color or colour
grep -E "(cat|dog)" pets.txt # cat or dog
Execution
Terminal window
echo -e "test\ntest1\ntest123\ntest1a" | grep -E "test[0-9]+"
Output
Terminal window
test1
test123
test1a
  • -E flag enables extended regex (ERE)
  • Cleaner syntax than BRE with + ? {n,m}
  • More intuitive than escaping in BRE
  • Recommended for complex patterns

Complex extended regex patterns

The pattern validates exact format - three digits, hyphen, two digits, hyphen, four digits, with ^ and $ anchors.

Code
Terminal window
# Complex patterns with extended regex
grep -E "^[0-9]{3}-[0-9]{2}-[0-9]{4}$" ssn.txt
grep -E "^[a-z]+@[a-z]+\.[a-z]+$" emails.txt
grep -E "^https?://" urls.txt
grep -E "^(admin|root):" /etc/passwd
# Combinations with modifiers
grep -E "(test|demo)_[0-9]{2,4}" files.txt
Execution
Terminal window
echo -e "123-45-6789\n12-45-6789\nabc-45-6789" | grep -E "^[0-9]{3}-[0-9]{2}-[0-9]{4}$"
Output
Terminal window
123-45-6789
  • {n,m} matches between n and m occurrences
  • {n} matches exactly n occurrences
  • Anchors ^ and $ ensure exact matches
  • Parentheses group patterns for | alternation

Anchors and Boundaries

Line and word boundary patterns

Line anchors for position matching

The $ anchor matches "error" only at the end of the line, not in the middle.

Code
Terminal window
# ^ = start of line
# $ = end of line
grep "^error" log.txt # lines starting with error
grep "\.log$" files.txt # lines ending with .log
grep "^$" file.txt # empty lines
grep "^[0-9]" data.txt # lines starting with digit
grep "success$" results.txt # lines ending with success
Execution
Terminal window
echo -e "error: failed\nwarning: error\nerror at end" | grep "error$"
Output
Terminal window
error at end
  • ^ matches position before first character
  • $ matches position after last character
  • ^$ together match entirely empty lines
  • Anchors match position, not actual content

Word boundaries in extended regex

Word boundaries \b match "test" only as a standalone word, not within "marketesting" or "testing".

Code
Terminal window
# Word boundary matching (requires -E or -P)
grep -E "\\btest\\b" file.txt # complete word
grep -E "^[a-z]+$" words.txt # exactly lowercase
grep -E "\\bserver\\b:" config.txt # word boundary match
# Alternative: use -w flag for word boundaries
grep -w "test" file.txt # simpler approach
Execution
Terminal window
echo -e "test word\nmarketesting\ntest: started\ntesting" | grep -E "\\btest\\b"
Output
Terminal window
test word
test: started
  • \b matches word boundaries (letter/non-letter transitions)
  • -w flag provides simpler word boundary matching
  • Anchors ^ and $ prevent partial matches

Repetition Operators

Matching repeated characters and patterns

Repetition with asterisk and plus

The + operator requires at least one 'u'. With *, zero or more would match "color" too.

Code
Terminal window
# * = zero or more of previous (BRE default)
# + = one or more of previous (requires -E)
grep "error*" log.txt # error, eror, errror (BRE)
grep -E "error+" log.txt # error, errorr, errror (ERE)
grep -E "a+b" file.txt # a, aa, aaa, ... followed by b
grep -E "0*1" file.txt # 1, 01, 001, etc
# Practical examples
grep "^#+$" readme.txt # lines of only # characters
grep -E "^-+$" file.txt # separator lines (dashes)
Execution
Terminal window
echo -e "color\ncolour\ncolouur\ncolr" | grep -E "colou+r"
Output
Terminal window
colour
colourr
  • * includes zero occurrences (matches "error" for pattern "error*")
  • + requires at least one (doesn't match "error" for pattern "error+")
  • Use -E for + operator
  • Without -E, need to escape: \+

Counting repetitions with braces

The {2,4} pattern matches 2 to 4 'a' characters, excluding single 'a' and 'aaaa'.

Code
Terminal window
# {n} = exactly n times
# {n,m} = between n and m times
# {n,} = n or more times
grep -E "a{2}" file.txt # aa, aaa, aaaa
grep -E "a{2,4}" file.txt # aa, aaa, aaaa
grep -E "[0-9]{3}" file.txt # exactly 3 digits
grep -E "[0-9]{2,}" file.txt # 2 or more digits
# Real-world examples
grep -E "[0-9]{3}-[0-9]{3}-[0-9]{4}" phones.txt # phone regex
Execution
Terminal window
echo -e "a\naa\naaa\naaaa\naaaaa" | grep -E "a{2,4}"
Output
Terminal window
aa
aaa
aaaa
  • {n,m} is more precise than * or +
  • Useful for validation patterns
  • Requires -E flag
  • BRE requires escaping: \{n,m\}

Output Control

Controlling what grep displays

Count Matches and Suppress Output

Count matching lines and suppress normal output

Count matching lines with -c

The -c flag returns count of matching lines (3) instead of printing them.

Code
Terminal window
# -c flag counts matching lines instead of printing them
grep -c "pattern" filename
# Shows number of lines matching, not the lines
grep -c "error" log.txt # outputs: 42
grep -c "warning" log.txt # outputs: 13
grep -c "^#" script.sh # count comment lines
# Combine with other patterns
grep -c "^" file.txt # total line count
Execution
Terminal window
echo -e "error\nwarning\nerror\nerror\ninfo" | grep -c "error"
Output
Terminal window
3
  • -c counts matching lines, not total matches
  • Useful for statistics and reporting
  • Returns 0 if no matches found
  • Faster than counting lines manually

Suppress output with -q

The -q flag suppresses output and returns exit code to check if pattern exists.

Code
Terminal window
# -q (quiet) suppresses output
# Returns exit code: 0 if match found, 1 otherwise
grep -q "pattern" filename
# Useful in scripts for conditional logic
if grep -q "error" log.txt; then
echo "Errors found"
fi
# Check if word exists in file
grep -q "^root:" /etc/passwd && echo "root user exists"
Execution
Terminal window
echo -e "apple\nbanana\ncherry" | grep -q "banana" && echo "found"
Output
Terminal window
found
  • -q returns exit code (0=found, 1=not found)
  • No output produced with -q
  • Useful in conditional statements and scripts
  • Faster than redirecting to /dev/null

Line Numbers and File Names

Display line numbers and file names in output

Display line numbers with -n

The -n flag shows line numbers (2 and 4) before each matching line.

Code
Terminal window
# -n flag displays line numbers before each match
grep -n "pattern" filename
# Shows line number and matched line
grep -n "error" log.txt
grep -n "TODO" code.py
grep -n "(function|method)" *.js
# Useful with head/tail for context
grep -n "pattern" file.txt | head -5
Execution
Terminal window
echo -e "line1\nerror: failed\nline3\nerror: retry\nline5" | grep -n "error"
Output
Terminal window
2:error: failed
4:error: retry
  • Line numbers are 1-based (first line is 1)
  • Useful for locating errors in code/logs
  • Can navigate directly to line with editor :N syntax
  • Combine with pipes for further filtering

Show file names with -H and -h

The -H flag shows filename with each match when searching multiple files.

Code
Terminal window
# -H flag shows filename for each match
grep -H "pattern" *.txt
# -h flag suppresses filename (default for single file)
grep -h "pattern" file1.txt file2.txt
# Combine -H with line numbers
grep -Hn "ERROR" *.log
# Useful with multiple file searches
grep -r -H "pattern" directory/
Execution
Terminal window
echo "error message" > /tmp/test1.txt && echo "error found" > /tmp/test2.txt && grep -H "error" /tmp/test*.txt
Output
Terminal window
/tmp/test1.txt:error message
/tmp/test2.txt:error found
  • -H shows filename (useful for multiple files)
  • -h suppresses filename (useful to avoid duplicates)
  • Default behavior varies by grep implementation
  • Combine -H and -n: grep -Hn pattern file produces file:line:text

Show Only Matched Text

Display only the matched portion of lines

Show only matched part with -o

The -o flag shows only matched patterns, not full lines.

Code
Terminal window
# -o flag shows only the matched text, not full lines
grep -o "pattern" filename
# Useful for extracting specific patterns
grep -o "[0-9]*\.[0-9]*" file.txt # numbers with decimals
grep -o "[a-z]*@[a-z]*" emails.txt # email addresses
grep -oE "https?://[^ ]+" urls.txt # URLs
# Count matches (not lines) with -o and -c
grep -o "word" file.txt | wc -l
Execution
Terminal window
echo "error: 123 warning: 456 error: 789" | grep -o "error: [0-9]*"
Output
Terminal window
error: 123
error: 789
  • -o shows only matched text, not full line
  • Useful for extracting data (numbers, emails, URLs)
  • Can pipe to other commands for further processing
  • One match per line in output

Extract patterns with -o and regex

The -o flag with -E extracts phone numbers matching the pattern.

Code
Terminal window
# Extract specific data from structured text
grep -oE "[0-9]{3}-[0-9]{3}-[0-9]{4}" data.txt # phone numbers
grep -oE "[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}" file.txt # emails
grep -oE "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" log.txt # IPs
# Count specific matches
grep -o "abc" myfile.txt | wc -l # count "abc" occurrences
Execution
Terminal window
echo "Call: 555-123-4567 or 555-987-6543" | grep -oE "[0-9]{3}-[0-9]{3}-[0-9]{4}"
Output
Terminal window
555-123-4567
555-987-6543
  • Perfect for data extraction from text
  • Combine with pipes for processing: grep -o "pattern" | sort | uniq
  • Works well with extended regex (-E)

Color Output and Byte Offsets

Highlight matches and show byte positions

Color output with highlight

The --color flag highlights matching text, useful for visual inspection.

Code
Terminal window
# --color flag highlights matches with color
grep --color "pattern" filename
# Force color output (useful in pipes)
grep --color=always "error" log.txt | less -R
# Disable color output
grep --color=never "pattern" file.txt
# Color in pipelines (useful for inspection)
cat log.txt | grep --color=always "error"
Execution
Terminal window
echo "error in line\nno match here\nerror again" | grep --color=always "error"
Output
Terminal window
error in line
error again
  • --color highlights the matched portion
  • Default is automatic color detection
  • Use --color=always in pipes to force coloring
  • Use --color=never to suppress coloring

Show byte offset with -b

The -b flag shows byte offset (10) where "def" begins in that line.

Code
Terminal window
# -b flag shows byte offset of matches
grep -b "pattern" filename
# Shows position from start of line where match begins
grep -b "error" log.txt
grep -bn "pattern" file.txt # with line numbers
# Useful for binary file analysis
grep -b "signature" binary_file | head
Execution
Terminal window
echo -e "123456789\nabcdefghij\n0123456789" | grep -b "def"
Output
Terminal window
10:abcdefghij
  • -b shows byte position from start of line
  • Useful for binary files and precise positioning
  • Can combine with -n for line and byte info
  • Less common flag but useful for specialized tasks

Context and Line Selection

Display context around matches and filter lines

Context Lines Around Matches

Show lines before and after matches

Show context with -B, -A, and -C

The -A 2 flag shows the matching line plus 2 lines after it.

Code
Terminal window
# -B NUM = lines before match
# -A NUM = lines after match
# -C NUM = lines before and after match
grep -B 2 "error" log.txt # 2 lines before
grep -A 3 "ERROR" log.txt # 3 lines after
grep -C 1 "pattern" file.txt # 1 line before and after
# Useful for understanding context
grep -B 5 -A 5 "Search term" document.txt
grep -C 2 "Connection refused" system.log
Execution
Terminal window
echo -e "start\nline2\nerror\nline4\nline5" | grep -A 2 "error"
Output
Terminal window
error
line4
line5
  • -A adds lines after the match
  • -B adds lines before the match
  • -C adds both before and after
  • NUM is the number of lines to display

Context with line numbers and colors

Multiple context groups are separated by dashes. Each match shows surrounding lines.

Code
Terminal window
# Combine context with other useful flags
grep -C 3 -n "pattern" file.txt # context + line numbers
grep -C 2 --color "error" log.txt # context + color
# Separate output with dashes (useful for multiple groups)
grep --color=always -C 2 "error" large.log | less -R
# Multiple occurrences show with separators
grep -B 1 -A 1 "pattern" file.txt
Execution
Terminal window
echo -e "line1\nline2\nerror message\nline4\nline5\nerror again\nline7" | grep -B 1 -A 1 "error"
Output
Terminal window
line2
error message
line4
--
line5
error again
line7
  • Dashes (--) separate different match groups
  • Very useful for understanding error context in logs
  • Combine with -n for precise line location
  • Better than scrolling through large files

Invert Match

Show lines NOT matching the pattern

Exclude pattern with -v

The -v flag inverts match, showing only lines NOT starting with 'a'.

Code
Terminal window
# -v flag shows lines NOT matching pattern
grep -v "pattern" filename
# Useful for filtering out unwanted lines
grep -v "^#" config.txt # exclude comments
grep -v "^$" file.txt # exclude empty lines
grep -v "debug" app.log # exclude debug logs
grep -v "exclude_this" data.txt # exclude specific text
Execution
Terminal window
echo -e "apple\nbanana\napricot\norange" | grep -v "^a"
Output
Terminal window
orange
  • -v negates the pattern (shows non-matching lines)
  • Useful for filtering out unwanted content
  • Works with any pattern or regex
  • Returns all non-matching lines

Multiple inverted patterns

Multiple -v flags exclude both "debug" and "info" lines, leaving only "error" lines.

Code
Terminal window
# Stack multiple -v flags to exclude multiple patterns
grep -v 'debug' -v 'info' log.txt
# Exclude multiple patterns
grep -v '^#' -v '^$' config.txt # no comments, no blank lines
# Combined with other flags
grep -vn "error" app.log # exclude errors with line numbers
grep -vic "pattern" file.txt # case-insensitive invert + count
Execution
Terminal window
echo -e "debug: test\ninfo: started\nerror: failed\ninfo: complete" | grep -v "^debug" | grep -v "^info"
Output
Terminal window
error: failed
  • Multiple -v flags provide AND logic (exclude all patterns)
  • Different from -e patterns which are OR logic
  • Useful for multi-stage filtering

Max Count and File Listing

Limit matches and show files with matches

Limit matches with -m

The -m 2 flag stops after finding 2 matches.

Code
Terminal window
# -m NUM flag stops after NUM matches
grep -m 5 "pattern" filename
# Shows only first N matching lines
grep -m 1 "error" log.txt # first error only
grep -m 10 "warning" app.log # first 10 warnings
# Useful for large files to get quick preview
grep -m 5 "todo" project.txt # first 5 TODOs
Execution
Terminal window
echo -e "error1\nerror2\nerror3\nerror4\nerror5" | grep -m 2 "error"
Output
Terminal window
error1
error2
  • -m NUM sets maximum number of matches to display
  • Grep stops reading file after NUM matches
  • Useful for performance on large files
  • Faster than showing all matches and piping to head

List files with matches

The -l flag shows only filenames containing the pattern, not the matching lines.

Code
Terminal window
# -l flag lists only filenames (one per line) with matches
grep -l "pattern" *.txt
# -L flag lists only filenames WITHOUT matches
grep -L "pattern" *.txt
# Useful for finding which files contain/lack content
grep -r -l "TODO" src/ # files with TODO comments
grep -r -L "license" docs/ # files without license header
Execution
Terminal window
echo "test" > /tmp/file1.txt && echo "other" > /tmp/file2.txt && grep -l "test" /tmp/file*.txt
Output
Terminal window
/tmp/file1.txt
  • -l lists filenames only (helpful for further processing)
  • -L lists filenames that DON'T match
  • Useful with xargs: grep -l "pattern" * | xargs cmd
  • Very fast since grep stops after first match

File and Directory Operations

Search across files and directories

File and Directory Exclusion

Skip specific files and directories from search

Exclude files by pattern

The --exclude flag skips .log files, showing only the match in file.txt.

Code
Terminal window
# --exclude filters specific file patterns
grep -r --exclude="*.log" "pattern" directory/
# Exclude multiple patterns
grep -r --exclude="*.log" --exclude="*.tmp" "pattern" src/
# Exclude directories to speed up search
grep -r --exclude-dir="node_modules" "pattern" project/
grep -r --exclude-dir=".git" --exclude-dir="*.log" "pattern" .
# Common exclusions
grep -r --exclude-dir=target --exclude-dir=build "pattern" project/
Execution
Terminal window
mkdir -p /tmp/excl_test && echo "search" > /tmp/excl_test/file.txt && echo "skip" > /tmp/excl_test/file.log && grep -r --exclude="*.log" "search\|skip" /tmp/excl_test
Output
Terminal window
/tmp/excl_test/file.txt:search
  • --exclude patterns skip specific file types
  • --exclude-dir skips entire directories
  • Multiple exclusions require separate flags
  • Greatly speeds up searches in large projects

Include only specific files

The --include flag searches only .py files, skipping the .java file.

Code
Terminal window
# --include filters to specific file patterns
grep -r --include="*.py" "pattern" src/
# Search only specific file types
grep -r --include="*.js" --include="*.ts" "import" src/
# Combine include and exclude
grep -r --include="*.log" --exclude="debug.log" "error" logs/
# More flexible than just excluding
grep -r --include="[Mm]akefile*" "target" .
Execution
Terminal window
mkdir -p /tmp/incl_test && echo "python" > /tmp/incl_test/script.py && echo "java" > /tmp/incl_test/Main.java && grep -r --include="*.py" "python\|java" /tmp/incl_test
Output
Terminal window
/tmp/incl_test/script.py:python
  • --include specifies which files to search
  • More precise control than --exclude
  • Multiple includes require separate flags
  • Useful for language-specific searches

Binary Files and Special Input

Handle binary files and null-separated input

Handle binary files

The -a flag treats input as text even if it contains binary data.

Code
Terminal window
# --binary-files specifies how to handle binary
grep --binary-files=text "pattern" binaryfile
# -a flag treats binary as text (like --binary-files=text)
grep -a "pattern" binaryfile
# Useful with binary files that contain text
grep -a "version" compiled_binary
# Skip binary files entirely
grep -r --binary-files=without-match "pattern" .
Execution
Terminal window
echo "Hello binary world" | grep -a "world"
Output
Terminal window
Hello binary world
  • Grep skips binary files by default
  • -a treats binary input as text characters
  • Useful for searching in compiled binaries
  • May produce garbage output with true binary

Null-separated input and output

The -z flag treats null bytes as line separators instead of newlines.

Code
Terminal window
# -z flag handles null-separated input/output
grep -z "pattern" null_separated_file
# Useful with find -print0 for safe handling
find . -name "*.txt" -print0 | xargs -0 grep "pattern"
# Process filenames with spaces safely
find . -type f -print0 | xargs -0 grep -z "pattern"
# Combine with other flags
grep -rz "pattern" directory/
Execution
Terminal window
printf "line1\0line2\0line3" | grep -z "line2"
Output
Terminal window
line2
  • -z handles null-delimited input
  • Important for xargs and find with -print0
  • Allows searching paths with special characters
  • Necessary for robust script handling

Practical Examples and Advanced Usage

Real-world scenarios and complex grep patterns

Real-World Use Cases

Practical examples of grep in common scenarios

Search and analyze log files

Extract specific error types from log entries using piped grep commands.

Code
Terminal window
# Count errors in log file
grep -c "ERROR" app.log
# Show recent errors with context
grep -n -A 2 "ERROR" app.log | tail -20
# Extract specific information
grep "timestamp:" server.log | grep -o "[0-9:-]*"
# Find patterns across multiple logs
grep -r "Connection refused" var/log/ | sort | uniq
# Get error summary
grep "ERROR" app.log | grep -o "code: [0-9]*" | sort | uniq -c
Execution
Terminal window
echo -e "2025-02-28 ERROR: db connection\n2025-02-28 ERROR: timeout\n2025-02-28 INFO: OK" | grep "ERROR" | grep -o "ERROR: [a-z]*"
Output
Terminal window
ERROR: db
ERROR: timeout
  • Combine grep commands for complex analysis
  • Use grep -o to extract specific data
  • Pipe to sort and uniq for summaries
  • Great for log analysis and debugging

Search source code

Find TODO comments in source code with line numbers for quick navigation.

Code
Terminal window
# Find function definitions
grep -rn "^function " src/
# Find TODO and FIXME comments
grep -r "TODO\|FIXME" src/ --include="*.js"
# Find unused imports
grep -r "^import" src/ | grep -v "from"
# Find break points (in debugging)
grep -rn "debugger;" src/
# Search class definitions
grep -rn "^class " src/ --include="*.js"
Execution
Terminal window
mkdir -p /tmp/src && echo -e "function test() {}\n// TODO: fix this\nfunction main() {}" > /tmp/src/app.js && grep -n "TODO" /tmp/src/app.js
Output
Terminal window
2:// TODO: fix this
  • Combine patterns for specific code elements
  • Use line numbers for quick editor navigation
  • Useful for code review and cleanup

Advanced Regular Expression Patterns

Complex regex patterns for specialized searches

Complex validation patterns

Validates email format using extended regex with character classes and anchors.

Code
Terminal window
# Email validation (basic)
grep -E "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$" emails.txt
# IP address validation
grep -E "^([0-9]{1,3}\.){3}[0-9]{1,3}$" ips.txt
# URL validation
grep -oE "https?://[^ ]+" urls.txt
# Phone number validation
grep -E "^\+?[1-9]\d{1,14}$" phones.txt
# Hexadecimal color codes
grep -oE "#[0-9a-fA-F]{6}" colors.txt
Execution
Terminal window
echo -e "user@example.com\ninvalid.email\ntest@domain.co.uk" | grep -E "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
Output
Terminal window
user@example.com
test@domain.co.uk
  • Regex validation is pattern-based, not perfect
  • Works well for basic format checking
  • Can be combined with other tools for perfect validation
  • Test patterns carefully before deployment

Negative lookahead and grep

Use pipes to negate patterns that grep doesn't support with lookahead.

Code
Terminal window
# Grep doesn't support lookahead, use alternatives
# Find lines WITHOUT a pattern (use -v)
grep -v "exclude_this" file.txt
# Find lines with pattern but NOT followed by another
grep "error" file.txt | grep -v "error: handled"
# Complex exclusions with multiple patterns
grep -v "debug\|test\|verbose" app.log
# Lines with pattern A but not pattern B
grep "function" code.js | grep -v "function test"
Execution
Terminal window
echo -e "error: critical\nerror: handled\nerror: warning\nerror: critical" | grep "error" | grep -v "error: handled"
Output
Terminal window
error: critical
error: warning
error: critical
  • Grep doesn't support lookahead/lookbehind assertions
  • Use pipes with -v to achieve similar results
  • Multiple -v flags work with AND logic
  • Efficient approach for most use cases

Performance Optimization

Tips for efficient grep usage on large files

Optimize grep performance

Fixed string search (-F) is fastest for literal patterns, useful for large files.

Code
Terminal window
# Use fixed string search instead of regex (fastest)
grep -F "literal text" large_file.txt
# Use -m to limit results on large files
grep -m 100 "pattern" huge.log
# Use -l to find files first, then grep specific ones
find . -name "*.log" | xargs grep "pattern"
# Exclude heavy directories early
grep -r --exclude-dir=node_modules --exclude-dir=.git "pattern" .
# Use word boundaries to eliminate false positives
grep -w "word" file.txt # avoids partial matches
Execution
Terminal window
seq 1 10000 | python3 -c "import sys; print('\n'.join(['test' + str(i) for i in range(10000)]))" | grep -F "test5000"
Output
Terminal window
test5000
  • -F (fixed string) is much faster than regex
  • -m limits results for quick previews
  • Exclude unnecessary directories with --exclude-dir
  • Use find | xargs for complex file selection

Parallel grep for distributed search

Parallel processing with xargs can speed up searching multiple files.

Code
Terminal window
# Use parallel grep on multiple files
find . -type f -name "*.log" | parallel grep "pattern"
# Or use xargs with multiple jobs
find . -type f | xargs -P 4 grep "pattern"
# Split large file and search parts
split -l 100000 huge.log part_
grep "pattern" part_* &
# GNU parallel syntax
ls *.log | parallel grep "pattern" {}
Execution
Terminal window
echo -e "test1\ntest2\ntest3" | xargs -P 2 grep "test"
Output
Terminal window
test1
test2
test3
  • xargs -P specifies number of parallel processes
  • Most beneficial with hundreds of files
  • GNU parallel is more flexible than xargs
  • Check available CPU before setting job count