linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
  • Introduction
  • Lessons
  • How it works
  • Simulator
  • Knowledge base
  • Interview prep
Index
Categories
All entries
Footer
linuxlab-TutorialsPricingAboutPrivacy & cookies
Copyright © 2026 LinuxLab. All rights reserved.
home/linux/kb/Commands/cmd-grep

kb/commands ── Commands ── beginner

grep: search lines by pattern

`grep` searches stdin or files for lines matching a regex. Key modes: `-E` (ERE), `-P` (PCRE), `-F` (fixed string), `-r` (recursive tree walk).

view as markdownaka: grep-command, grep-regex, egrep, fgrep

Basic syntax

grep [OPTIONS] PATTERN [FILE...]

By default grep uses BRE (Basic Regular Expressions). That means +, ?, (, ), {, } in the pattern are treated as literals unless escaped. To get the usual regex behavior, use -E (or egrep, which is the same thing):

bash
grep    'foo\+'  file       # BRE: + must be escaped
grep -E 'foo+'   file       # ERE: no escape needed

Key flags

flagmeaning
-icase-insensitive
-vinvert (lines with NO match)
-nprefix each line with its line number
-cprint only the count of matching lines
-lprint only the names of files that have a match
-Lopposite: files with NO match
-oprint only the matched part of each line
-wmatch whole words only
-xmatch whole lines only
-r / -Rrecursive tree walk (R follows symlinks)
-A N / -B N / -C Ncontext: After / Before / Around
--include='*.py'restrict files matched by -r
--exclude-dir=.gitskip a directory

Regex modes

bash
grep -F 'a.b.c'  file       # -F: fixed string, dots are literal dots
grep    'a.b'    file       # BRE: . = any character
grep -E '^[0-9]+$' file     # ERE: [], +, {}, () work without \
grep -P '\d{3}-\d{4}'  file # PCRE: \d, \w, look-ahead, named groups

PCRE gives the most expressive patterns (lookahead, non-greedy, Perl-style character classes), but requires grep built with --enable-perl-regexp (Ubuntu ships with it enabled by default).

Recursive search

bash
grep -rn 'TODO' .                         # all TODOs in the project, with line numbers
grep -rni --include='*.py' 'fixme' src/   # only in .py files
grep -rln 'API_KEY' /etc                  # names of files that mention it
grep -rn 'password' . --exclude-dir=.git --exclude-dir=node_modules

Without -r, grep will complain: Is a directory.

Context

bash
grep -n -B 2 -A 2 'ERROR' app.log    # 2 lines before and after
grep -C 3 'panic' /var/log/syslog     # 3 lines on each side

Anchors and groups

bash
grep '^Host'  ~/.ssh/config        # start of line
grep '\.log$' filelist             # end of line
grep -E '\b[0-9]{1,3}(\.[0-9]{1,3}){3}\b' file   # IPv4 (see [[ipv4-addressing]])
grep -Eo '[a-z0-9.]+@[a-z0-9.]+'  # extract email addresses

Combining with other tools

The most common pattern is a pipe from cmd-find:

bash
find . -type f -name '*.conf' -print0 | xargs -0 grep -l 'listen 80'

▸find all config files that mention "listen 80"

Or from the output of another command:

bash
ps aux | grep -v grep | grep nginx       # classic "exclude the grep line itself"
ss -tn | grep ESTAB                      # ESTABLISHED sessions
dmesg | grep -i 'oom'                    # see [[oom-killer]]

The | grep -v grep idiom is needed because ps aux | grep nginx would also match the grep nginx process in the ps output.

Exit codes (important for scripts)

  • 0 - at least one match was found
  • 1 - no matches
  • 2 - error (missing file, bad regex)

In bash:

bash
if grep -q ERROR app.log; then
  echo "errors present"
fi

-q (quiet) produces no output; it only sets the exit code.

ripgrep as a modern alternative

rg (ripgrep) is orders of magnitude faster than grep -r. It respects .gitignore automatically, runs searches in parallel, and uses SIMD. On large repositories the difference is dramatic. That said, grep is POSIX and available everywhere, so knowing it is essential.

§ команды

bash
grep -rn 'TODO' .

All TODOs in the project, recursive, with line numbers

bash
grep -i error /var/log/syslog | tail

Last lines containing error/Error/ERROR (case-insensitive)

bash
grep -c '^GET' access.log

Count of GET requests in the log (number only, no lines)

bash
grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' access.log

Lines starting with an IPv4 address (ERE, no backslashes needed)

bash
grep -rln --include='*.py' 'import requests' .

Names of .py files that import requests

bash
grep -B 2 -A 5 'panic' /var/log/kern.log

Context around a kernel panic: 2 lines before, 5 after

§ см. также

  • cmd-findfind: search files by predicates`find` walks a directory tree and applies predicates (name, type, time, size, permissions). Actions: `-print` (default), `-delete`, `-exec`, `| xargs`.
  • cmd-sedsed: stream editorsed is a stream editor: it applies commands (`s/a/b/`, `d`, `p`, ...) to each line. `-i` edits a file in place; `-E` enables ERE; the address range `/start/,/end/` filters a block. Hold space is a second buffer.
  • cmd-awkawk: field-oriented processing of structured textawk splits a line into fields by FS (default is whitespace) and applies pattern { action }. `$1..$NF`, `NR` (a counter), BEGIN/END for a prologue and totals. It covers 80% of "process the columns" tasks without Python.
  • cmd-jqjq: JSON queries and transformationjq is a query language for JSON in the shell. Use .field, .array[], select(...), map(...), and in-expression pipes via |. -r strips quotes, -c packs output into a single line. Works well in curl + jq + grep pipelines.
  • file-permissionsFile permissions: rwx and chmodEvery file has three permission sets: for the owner, the group, and others. Each set is three bits: read (r), write (w), execute (x). You change them with `chmod`.

§ упоминается в уроках

  • ›beginner-11-find-and-grep
  • ›intermediate-10-xargs-and-parallel
Footer
linuxlab-
Copyright © 2026 LinuxLab. All rights reserved.
Tutorials
Pricing
About
Privacy & cookies