---
title: "Grep"
description: "Complete grep reference with pattern matching, regular expressions, flags, context options, and practical examples for searching text files"
author: "Mohammad Abu Mattar"
canonical: https://mkabumattar.com/cheatsheets/grep
---

# Grep

## Best Practices for Grep Usage

- **Always quote patterns** to prevent shell interpretation of special characters
- **Use -E flag for complex patterns** to avoid escaping issues with basic regex
- **Test patterns on sample data** before running on production systems
- **Use -n with debugging** to quickly navigate to errors in code
- **Combine with pipes** to create powerful data processing pipelines
- **Use -F for literal strings** when you don't need regex (much faster)
- **Use -w for word boundaries** to avoid partial word matches in code
- **Use anchors extensively** (^ for start, $ for end) to match precise patterns
- **Exclude directories early** with grep -r to improve performance
- **Use --color=always in pipes** to highlight matches in complex pipelines

## Common Errors and Solutions

- **error: "No such file or directory"** → Check file path exists and permissions are correct
- **error: "grep: (standard input): No such device"** → Check input method; ensure piped input is valid
- **error: "Invalid regular expression"** → Check regex syntax; escape special characters or use -F for literals
- **error: "Binary file matches"** → Use -a flag or --binary-files=text to treat as text
- **error: "Nothing found when expecting matches"** → Verify pattern is correct; test pattern syntax with sample data
- **error: "Searching too slowly"** → Use -F for literals, limit results with -m, exclude directories with --exclude-dir

---

ref: https://man7.org/linux/man-pages/man1/grep.1.html

## Getting Started

Introduction to grep and basic concepts

### What is Grep

Understanding grep and its use cases for text searching

**Keywords:** grep, search, pattern, text, files

#### Grep overview and basic usage

```bash
# 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
```

_exec_
```bash
echo -e "apple\nbanana\ncherry\napricot" | grep "ap"
```

_output_
```bash
apple
apricot
```

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

- 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

```bash
# 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
```

_exec_
```bash
echo -e "error: connection failed\ninfo: starting\nerror: timeout" | grep "^error"
```

_output_
```bash
error: connection failed
error: timeout
```

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

- 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

**Best practices:**

- Use single quotes to protect patterns from shell interpretation
- Test patterns on small files before running on large datasets
- Use -E for consistent extended regex syntax
- Combine multiple flags for efficiency

**Common errors:**

- **No such file or directory**: Verify file path exists and check spelling

### Installation and Setup

Installing grep and verifying functionality

**Keywords:** install, setup, version, grepDependencies

#### Verify grep installation

```bash
# Check if grep is installed
which grep

# Display grep version
grep --version

# Show grep help
grep --help | head -20
```

_exec_
```bash
grep --version
```

_output_
```bash
grep (GNU grep) 3.7
Copyright (C) 2021 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later.
```

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

- 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

```bash
# 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
```

_exec_
```bash
which grep && grep --version | head -1
```

_output_
```bash
/usr/bin/grep
grep (GNU grep) 3.7
```

Installation of grep across different Linux distributions and macOS systems.

- 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

**Best practices:**

- Use system package manager to install grep
- On macOS, consider installing GNU grep for compatibility
- Verify installation with --version flag

**Common errors:**

- **grep: command not found**: Install grep using package manager or check PATH

## Basic Pattern Matching

Simple text search and basic pattern techniques

### Simple Text Search

Basic pattern matching for literal text

**Keywords:** search, pattern, literal, text, basic

#### Search for literal text in files

```bash
# Search for a pattern in a file
grep "pattern" filename

# Search in multiple files
grep "pattern" file1 file2 file3

# Search with different patterns
grep "hello" sample.txt
grep "error" log.txt
grep "TODO" code.py
```

_exec_
```bash
echo -e "function test() {\n  console.log('hello')\n}\ntest('world')" | grep "hello"
```

_output_
```bash
console.log('hello')
```

Grep searches for any line containing the pattern "hello" anywhere in the line.

- Grep is case-sensitive by default
- Pattern is a substring match (anywhere in line)
- Returns full line containing match, not just the matched text
- Returns nothing if no matches found

#### Read from standard input

```bash
# Pipe command output to grep
cat file.txt | grep "pattern"

# Use echo to create input
echo "test string" | grep "test"

# Chain multiple commands
cat log.txt | grep "error" | grep "database"
```

_exec_
```bash
echo -e "line1\nerror: failed\nline3\nerror: retry" | grep "error"
```

_output_
```bash
error: failed
error: retry
```

Grep processes standard input when no file is specified, useful in pipelines.

- Use pipe | to send data to grep
- Grep waits for input from stdin if no file given
- Useful in command pipelines for filtering
- Can filter output from other commands

**Best practices:**

- Quote patterns to prevent shell interpretation
- Use grep as a filter in pipelines
- Test with small amounts of data first

**Common errors:**

- **grep: command not found**: Grep not in PATH; install or add to PATH

### Case-Insensitive Search

Matching patterns regardless of letter case

**Keywords:** case, insensitive, flag, ignore, case-i

#### Case-insensitive search with -i flag

```bash
# Search ignoring case with -i flag
grep -i "pattern" filename

# Works for any case combination
grep -i "ERROR" file.txt    # matches: error, Error, ERROR
grep -i "hello" text.txt    # matches: hello, Hello, HELLO
```

_exec_
```bash
echo -e "Hello World\nhello world\nHELLO WORLD" | grep -i "hello"
```

_output_
```bash
Hello World
hello world
HELLO WORLD
```

The -i flag makes grep ignore case differences, matching all variations of the pattern.

- -i stands for --ignore-case
- Matches regardless of uppercase/lowercase
- Useful for log files with inconsistent capitalization
- Works with literal text and regular expressions

#### Case-insensitive search in multiple files

```bash
# Search multiple files ignoring case
grep -i "Warning" *.log

# Combine with line numbers
grep -in "ERROR" error.log
grep -in "info" system.log
```

_exec_
```bash
echo -e "WARNING: disk full\nWarning: memory\nwARNING: cpu" | grep -i "warning"
```

_output_
```bash
WARNING: disk full
Warning: memory
wARNING: cpu
```

Case-insensitive search matches all variations having the pattern.

- Useful for searching logs with variable capitalization
- Can combine -i with other flags like -n or -c
- Works effectively in pipelines

**Best practices:**

- Use -i for log file searching where case varies
- Combine with -n to show line numbers
- Use in pipes to filter case-insensitive results

**Common errors:**

- **No output when expecting matches**: Check if -i flag is used for case variations

### Whole Word Matching

Match complete words without partial matches

**Keywords:** word, boundary, whole, -w, complete

#### Match whole words with -w flag

```bash
# -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"
```

_exec_
```bash
echo -e "the cat sat\nconcatenate strings\ncat is here" | grep -w "cat"
```

_output_
```bash
the cat sat
cat is here
```

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

- -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

```bash
# 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"
```

_exec_
```bash
echo -e "The quick brown fox\nthe lazy dog\nThey will go" | grep -iw "the"
```

_output_
```bash
The quick brown fox
the lazy dog
```

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

- -iw combines ignore-case and word-regexp
- More flexible searching for code and logs
- Avoids false positives from partial matches

**Best practices:**

- Use -w when searching for specific keywords in code
- Combine -w with -i for flexible matching
- Use -w to avoid partial word matches in data

**Common errors:**

- **Losing expected matches with word boundaries**: Verify word boundaries with -w; some punctuation may affect matching

### Whole Line Matching

Match patterns that span entire lines

**Keywords:** line, exact, whole, -x, anchors

#### Match exact lines with -x flag

```bash
# -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
```

_exec_
```bash
echo -e "test\ntest123\nmy test\nonlytest" | grep -x "test"
```

_output_
```bash
test
```

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

- -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

```bash
# 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
```

_exec_
```bash
echo -e "123\n12\n1234\n12a" | grep -x "[0-9][0-9][0-9]"
```

_output_
```bash
123
```

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

- -x requires complete line match including spaces
- Combine with -E for extended regex
- Useful for structured data validation

**Best practices:**

- Use -x for exact line matching in configuration files
- Combine -x with -E for precise pattern validation
- Use -x to avoid partial line matches

**Common errors:**

- **Pattern does not match when appearing in line**: -x requires exact line match; use partial pattern match without -x

### Multiple Patterns

Search for multiple patterns using different methods

**Keywords:** multiple, patterns, -e, or, alternation

#### Match multiple patterns with -e flag

```bash
# 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
```

_exec_
```bash
echo -e "error: failed\nwarning: deprecated\ninfo: started\nerror: retry" | grep -e "error" -e "warning"
```

_output_
```bash
error: failed
warning: deprecated
error: retry
```

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

- 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

```bash
# 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
```

_exec_
```bash
echo -e "apple fruit\nbroccoli vegetable\nstrawberry fruit\ncarrot vegetable" | grep -E "fruit|vegetable"
```

_output_
```bash
apple fruit
broccoli vegetable
strawberry fruit
carrot vegetable
```

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

- -E enables extended regular expressions
- Pipe | provides cleaner syntax for multiple patterns
- Works with groups: (pattern1|pattern2)
- More flexible than multiple -e flags

**Best practices:**

- Use -E with | for cleaner multiple pattern syntax
- Use multiple -e for simple literal patterns
- Combine with -i for case-insensitive matching

**Common errors:**

- **Patterns not matching as expected**: Escape special regex characters or use -F for literal text

## Regular Expressions

Advanced pattern matching using regular expressions

### Basic Regular Expressions

Basic regex patterns and syntax

**Keywords:** regex, regular, expression, pattern, basic

#### Basic regex metacharacters

```bash
# 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
```

_exec_
```bash
echo -e "error: failed\nwarning: check\nerror: retry\ninfo: started" | grep "^error"
```

_output_
```bash
error: failed
error: retry
```

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

- 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

```bash
# 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
```

_exec_
```bash
echo -e "test1\ntest2a\nrandom\ntest" | grep "test[0-9]"
```

_output_
```bash
test1
test2a
```

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

- [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

**Best practices:**

- Use character classes for flexible pattern matching
- Anchor patterns with ^ and $ for precise matches
- Test complex patterns on sample data first

**Common errors:**

- **Extended regex needs flag**: Use -E flag for extended regex with +, ?, |

### Extended Regular Expressions

Enhanced regex syntax with -E flag

**Keywords:** extended, regex, -E, ERE, flag

#### Extended regex patterns with -E

```bash
# 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
```

_exec_
```bash
echo -e "test\ntest1\ntest123\ntest1a" | grep -E "test[0-9]+"
```

_output_
```bash
test1
test123
test1a
```

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

- -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

```bash
# 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
```

_exec_
```bash
echo -e "123-45-6789\n12-45-6789\nabc-45-6789" | grep -E "^[0-9]{3}-[0-9]{2}-[0-9]{4}$"
```

_output_
```bash
123-45-6789
```

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

- {n,m} matches between n and m occurrences
- {n} matches exactly n occurrences
- Anchors ^ and $ ensure exact matches
- Parentheses group patterns for | alternation

**Best practices:**

- Use -E for cleaner pattern syntax
- Always quote patterns to prevent shell interpretation
- Test patterns with known inputs first

**Common errors:**

- **Invalid regular expression**: Check syntax; use -F for literal text if pattern appears invalid

### Anchors and Boundaries

Line and word boundary patterns

**Keywords:** anchor, boundary, start, end, ^, $, \b

#### Line anchors for position matching

```bash
# ^ = 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
```

_exec_
```bash
echo -e "error: failed\nwarning: error\nerror at end" | grep "error$"
```

_output_
```bash
error at end
```

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

- ^ 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

```bash
# 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
```

_exec_
```bash
echo -e "test word\nmarketesting\ntest: started\ntesting" | grep -E "\\btest\\b"
```

_output_
```bash
test word
test: started
```

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

- \b matches word boundaries (letter/non-letter transitions)
- -w flag provides simpler word boundary matching
- Anchors ^ and $ prevent partial matches

**Best practices:**

- Use ^ to match lines starting with pattern
- Use $ to match lines ending with pattern
- Use -w instead of \b for simpler word matching
- Combine anchors for precise matching

**Common errors:**

- **Matches not starting at beginning**: Add ^ anchor to force start-of-line matching

### Repetition Operators

Matching repeated characters and patterns

**Keywords:** repetition, quantifier, *, +, ?, {n,m}

#### Repetition with asterisk and plus

```bash
# * = 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)
```

_exec_
```bash
echo -e "color\ncolour\ncolouur\ncolr" | grep -E "colou+r"
```

_output_
```bash
colour
colourr
```

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

- * 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

```bash
# {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
```

_exec_
```bash
echo -e "a\naa\naaa\naaaa\naaaaa" | grep -E "a{2,4}"
```

_output_
```bash
aa
aaa
aaaa
```

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

- {n,m} is more precise than * or +
- Useful for validation patterns
- Requires -E flag
- BRE requires escaping: \{n,m\}

**Best practices:**

- Use * for zero or more matches
- Use + with -E for one or more matches
- Use {n,m} for precise repetition counts
- Test repetition patterns on sample data

**Common errors:**

- **Invalid regular expression**: For {n,m}, use -E flag or escape with \{ \}

## Output Control

Controlling what grep displays

### Count Matches and Suppress Output

Count matching lines and suppress normal output

**Keywords:** count, -c, suppress, -q, quiet

#### Count matching lines with -c

```bash
# -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
```

_exec_
```bash
echo -e "error\nwarning\nerror\nerror\ninfo" | grep -c "error"
```

_output_
```bash
3
```

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

- -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

```bash
# -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"
```

_exec_
```bash
echo -e "apple\nbanana\ncherry" | grep -q "banana" && echo "found"
```

_output_
```bash
found
```

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

- -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

**Best practices:**

- Use -c for counting matches in reports
- Use -q in shell scripts for conditionals
- [object Object]

**Common errors:**

- **Unexpected output with -c**: -c returns count, not lines; use without -c for lines

### Line Numbers and File Names

Display line numbers and file names in output

**Keywords:** line, number, -n, file, -H, -h

#### Display line numbers with -n

```bash
# -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
```

_exec_
```bash
echo -e "line1\nerror: failed\nline3\nerror: retry\nline5" | grep -n "error"
```

_output_
```bash
2:error: failed
4:error: retry
```

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

- 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

```bash
# -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/
```

_exec_
```bash
echo "error message" > /tmp/test1.txt && echo "error found" > /tmp/test2.txt && grep -H "error" /tmp/test*.txt
```

_output_
```bash
/tmp/test1.txt:error message
/tmp/test2.txt:error found
```

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

- -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

**Best practices:**

- Always use -n when debugging code/log issues
- Use -H explicitly when searching multiple files
- Combine -Hn for best navigation information

**Common errors:**

- **No file names shown**: Use -H flag explicitly for multiple files

### Show Only Matched Text

Display only the matched portion of lines

**Keywords:** matched, text, -o, output, only

#### Show only matched part with -o

```bash
# -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
```

_exec_
```bash
echo "error: 123 warning: 456 error: 789" | grep -o "error: [0-9]*"
```

_output_
```bash
error: 123
error: 789
```

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

- -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

```bash
# 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
```

_exec_
```bash
echo "Call: 555-123-4567 or 555-987-6543" | grep -oE "[0-9]{3}-[0-9]{3}-[0-9]{4}"
```

_output_
```bash
555-123-4567
555-987-6543
```

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

- Perfect for data extraction from text
- Combine with pipes for processing: grep -o "pattern" | sort | uniq
- Works well with extended regex (-E)

**Best practices:**

- Use -o for extracting specific patterns
- Combine -o with pipes for data processing
- Use -oE for complex pattern extraction

**Common errors:**

- **No matches displayed**: Verify pattern exactly matches; test with -E if using complex regex

### Color Output and Byte Offsets

Highlight matches and show byte positions

**Keywords:** color, highlight, -b, offset, bytes

#### Color output with highlight

```bash
# --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"
```

_exec_
```bash
echo "error in line\nno match here\nerror again" | grep --color=always "error"
```

_output_
```bash
error in line
error again
```

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

- --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

```bash
# -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
```

_exec_
```bash
echo -e "123456789\nabcdefghij\n0123456789" | grep -b "def"
```

_output_
```bash
10:abcdefghij
```

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

- -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

**Best practices:**

- Use --color=always in pipes for better visibility
- Use -b when precise byte positions are needed
- Combine --color with other flags for clarity

**Common errors:**

- **No color in output**: Use --color=always flag explicitly

## Context and Line Selection

Display context around matches and filter lines

### Context Lines Around Matches

Show lines before and after matches

**Keywords:** context, -B, before, -A, after, -C

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

```bash
# -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
```

_exec_
```bash
echo -e "start\nline2\nerror\nline4\nline5" | grep -A 2 "error"
```

_output_
```bash
error
line4
line5
```

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

- -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

```bash
# 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
```

_exec_
```bash
echo -e "line1\nline2\nerror message\nline4\nline5\nerror again\nline7" | grep -B 1 -A 1 "error"
```

_output_
```bash
line2
error message
line4
--
line5
error again
line7
```

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

- 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

**Best practices:**

- Use -C 2 or -C 3 for general context viewing
- Combine with -n for location information
- Use in pipes to large.log files for navigation

**Common errors:**

- **Too much output**: Reduce context numbers (-C 1 instead of -C 5)

### Invert Match

Show lines NOT matching the pattern

**Keywords:** invert, -v, negate, exclude, not

#### Exclude pattern with -v

```bash
# -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
```

_exec_
```bash
echo -e "apple\nbanana\napricot\norange" | grep -v "^a"
```

_output_
```bash
orange
```

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

- -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

```bash
# 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
```

_exec_
```bash
echo -e "debug: test\ninfo: started\nerror: failed\ninfo: complete" | grep -v "^debug" | grep -v "^info"
```

_output_
```bash
error: failed
```

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

- Multiple -v flags provide AND logic (exclude all patterns)
- Different from -e patterns which are OR logic
- Useful for multi-stage filtering

**Best practices:**

- Use -v to filter out known unwanted content
- Combine with other patterns for precise filtering
- Use -v to remove comments and blank lines from configs

**Common errors:**

- **Not getting all non-matching lines**: Verify pattern syntax; test with sample data

### Max Count and File Listing

Limit matches and show files with matches

**Keywords:** max, -m, count, files, -l, -L

#### Limit matches with -m

```bash
# -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
```

_exec_
```bash
echo -e "error1\nerror2\nerror3\nerror4\nerror5" | grep -m 2 "error"
```

_output_
```bash
error1
error2
```

The -m 2 flag stops after finding 2 matches.

- -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

```bash
# -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
```

_exec_
```bash
echo "test" > /tmp/file1.txt && echo "other" > /tmp/file2.txt && grep -l "test" /tmp/file*.txt
```

_output_
```bash
/tmp/file1.txt
```

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

- -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

**Best practices:**

- Use -m for quick previews of large files
- Use -l with xargs for batch operations
- Use -L to find files missing specific content

**Common errors:**

- **Missing filenames**: Use -l flag explicitly to get filenames

## File and Directory Operations

Search across files and directories

### Recursive Directory Search

Search patterns across multiple files and directories

**Keywords:** recursive, -r, directory, files, tree

#### Recursive search with -r

```bash
# -r flag searches directories recursively
grep -r "pattern" directory/

# Searches all files in directory and subdirectories
grep -r "TODO" src/              # find TODOs in code
grep -r "error" logs/            # search all log files
grep -r "function test" project/ # search all files

# Show filenames with results
grep -r -H "pattern" directory/
grep -rn "pattern" src/          # with line numbers
```

_exec_
```bash
mkdir -p /tmp/search_test/sub && echo "test line" > /tmp/search_test/file1.txt && echo "test data" > /tmp/search_test/sub/file2.txt && grep -r "test" /tmp/search_test
```

_output_
```bash
/tmp/search_test/file1.txt:test line
/tmp/search_test/sub/file2.txt:test data
```

The -r flag searches recursively through all subdirectories.

- -r searches directories recursively
- Includes all files in subdirectories
- Shows filename by default with -r
- Useful for code search across projects

#### Follow symlinks with -R

```bash
# -R flag follows symbolic links (vs -r which doesn't)
grep -R "pattern" directory/

# Searches through symlinked directories
grep -R "config" /
grep -Rn "pattern" src/

# Difference from -r
# -r: skip symlinks
# -R: follow symlinks (like -r --dereference)

# Exclude patterns for more control
grep -R --exclude="*.log" "pattern" src/
```

_exec_
```bash
mkdir -p /tmp/test_symlink/real && echo "found" > /tmp/test_symlink/real/file.txt && ln -s real /tmp/test_symlink/link && grep -R "found" /tmp/test_symlink
```

_output_
```bash
/tmp/test_symlink/real/file.txt:found
/tmp/test_symlink/link/file.txt:found
```

The -R flag follows symlinks, so both real and linked paths are searched.

- -R follows symbolic links (-r does not)
- Important for complex directory structures
- Can cause infinite loops with circular symlinks
- Use --exclude-dir to skip problematic directories

**Best practices:**

- Use -r for most directory searches
- Use -R when symlinks must be followed
- Combine with -n for file location information

**Common errors:**

- **Searching too slowly**: Use --exclude-dir to skip node_modules, .git, etc

### File and Directory Exclusion

Skip specific files and directories from search

**Keywords:** exclude, --exclude, --exclude-dir, include, skip

#### Exclude files by pattern

```bash
# --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/
```

_exec_
```bash
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_
```bash
/tmp/excl_test/file.txt:search
```

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

- --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

```bash
# --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" .
```

_exec_
```bash
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_
```bash
/tmp/incl_test/script.py:python
```

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

- --include specifies which files to search
- More precise control than --exclude
- Multiple includes require separate flags
- Useful for language-specific searches

**Best practices:**

- Use --exclude-dir for .git, node_modules, build
- Use --include for language-specific searches
- Combine include and exclude for precise control

**Common errors:**

- **Pattern not found in expected files**: Verify file inclusion/exclusion patterns match correctly

### Binary Files and Special Input

Handle binary files and null-separated input

**Keywords:** binary, -a, , -z, special

#### Handle binary files

```bash
# --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" .
```

_exec_
```bash
echo "Hello binary world" | grep -a "world"
```

_output_
```bash
Hello binary world
```

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

- 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

```bash
# -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/
```

_exec_
```bash
printf "line1\0line2\0line3" | grep -z "line2"
```

_output_
```bash
line2
```

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

- -z handles null-delimited input
- Important for xargs and find with -print0
- Allows searching paths with special characters
- Necessary for robust script handling

**Best practices:**

- Use -a for searching in binary files cautiously
- Use -z with find -print0 for safe file handling
- Skip binary files with --binary-files=without-match in code searches

**Common errors:**

- **Binary file matches (standard input)**: Use -a flag to treat as text, or skip binary files

## Practical Examples and Advanced Usage

Real-world scenarios and complex grep patterns

### Real-World Use Cases

Practical examples of grep in common scenarios

**Keywords:** practical, examples, real-world, use-cases, scenarios

#### Search and analyze log files

```bash
# 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
```

_exec_
```bash
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_
```bash
ERROR: db
ERROR: timeout
```

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

- 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

```bash
# 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"
```

_exec_
```bash
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_
```bash
2:// TODO: fix this
```

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

- Combine patterns for specific code elements
- Use line numbers for quick editor navigation
- Useful for code review and cleanup

**Best practices:**

- Use -n for easy navigation in editors
- Combine grep with pipes to process results
- Save complex grep commands as aliases

**Common errors:**

- **Output is empty or unexpected**: Test pattern on small sample first; check file encoding

### Advanced Regular Expression Patterns

Complex regex patterns for specialized searches

**Keywords:** advanced, regex, patterns, complex, specialized

#### Complex validation patterns

```bash
# 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
```

_exec_
```bash
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_
```bash
user@example.com
test@domain.co.uk
```

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

- 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

```bash
# 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"
```

_exec_
```bash
echo -e "error: critical\nerror: handled\nerror: warning\nerror: critical" | grep "error" | grep -v "error: handled"
```

_output_
```bash
error: critical
error: warning
error: critical
```

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

- 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

**Best practices:**

- Test complex patterns on sample data
- Use extended regex (-E) for cleaner syntax
- Use pipes to handle complex logic

**Common errors:**

- **Lookahead assertions not supported**: Use grep -v with pipes instead of lookahead

### Performance Optimization

Tips for efficient grep usage on large files

**Keywords:** performance, optimization, efficiency, large, files

#### Optimize grep performance

```bash
# 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
```

_exec_
```bash
seq 1 10000 | python3 -c "import sys; print('\n'.join(['test' + str(i) for i in range(10000)]))" | grep -F "test5000"
```

_output_
```bash
test5000
```

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

- -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

```bash
# 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" {}
```

_exec_
```bash
echo -e "test1\ntest2\ntest3" | xargs -P 2 grep "test"
```

_output_
```bash
test1
test2
test3
```

Parallel processing with xargs can speed up searching multiple files.

- 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

**Best practices:**

- Use -F for literal string searches
- Use -l to find files first, then process
- Exclude heavy directories to speed up -r searches
- Use parallel processing for multiple large files

**Common errors:**

- **Grep is too slow**: Use -F for literals, -m to limit, exclude directories
