6.6 Regular Expressions & grep, egrep, fgrep (103.7)
Key Takeaways
Regular expressions fall into two primary POSIX standards: Basic Regular Expressions (BRE, default in
grepandsed) and Extended Regular Expressions (ERE, enabled viagrep -Eoregrep).In BRE, metacharacters
+,?,{n,m},( ), and|must be escaped with a backslash (\+,\?,\{n,m\},\( \),\|) to activate special meaning; in ERE, they function as metacharacters natively.Line anchors match text boundaries:
^matches line beginning,$matches line ending, and^$matches empty lines.POSIX character classes (e.g.
[[:alnum:]],[[:digit:]],[[:space:]]) provide locale-independent character matching inside bracket expressions.The
grepfamily includesgrep(BRE),egrep/grep -E(ERE), andfgrep/grep -F(fixed literal strings, bypassing regex compilation for maximum throughput).
6.6 Regular Expressions & grep, egrep, fgrep
Quick Summary: Regular Expressions (Regex) provide a formal pattern-matching grammar for scanning, parsing, and filtering text streams in Linux. POSIX defines two primary dialects: Basic Regular Expressions (BRE) and Extended Regular Expressions (ERE). Administrators use the
grepfamily—comprising standardgrep(BRE),egrep/grep -E(ERE), andfgrep/grep -F(fixed literal string matching)—to locate log patterns, extract configuration parameters, and audit system files.
1. Regular Expression Flavors: BRE vs. ERE
The fundamental distinction between Basic and Extended Regular Expressions lies in how metacharacters and quantifiers are interpreted by default.
| Regex Feature | Metacharacter | Basic Regular Expression (BRE) Syntax | Extended Regular Expression (ERE) Syntax | Functional Matching Definition |
|---|---|---|---|---|
| Any Character | . | . | . | Matches any single character except newline (\n). |
| Line Start Anchor | ^ | ^ | ^ | Matches the position immediately at the beginning of a line. |
| Line End Anchor | $ | $ | $ | Matches the position immediately at the end of a line. |
| Zero or More | * | * | * | Matches zero or more occurrences of the preceding element. |
| One or More | + | \+ (Requires Backslash) | + (Native) | Matches one or more occurrences of the preceding element. |
| Zero or One | ? | \? (Requires Backslash) | ? (Native) | Matches zero or one occurrence (makes preceding element optional). |
| Interval Count | {n,m} | \{n,m\} (Requires Backslash) | {n,m} (Native) | Matches between and occurrences of the preceding element. |
| Alternation (OR) | | | \| (Requires Backslash) | | (Native) | Matches either the expression to its left OR to its right. |
| Grouping | ( ) | \( \) (Requires Backslash) | ( ) (Native) | Groups sub-expressions for quantifiers or capture boundaries. |
⚠️ LPIC-1 Trap — The Escaping Inversion:
- In BRE (
grep):+,?,{ },( ), and|are treated as literal characters unless escaped with a backslash (\+,\?,\{ \},\( \),\|).- In ERE (
grep -E/egrep):+,?,{ },( ), and|are metacharacters by default. Escaping them (\+) forces literal matching!
2. Anchors, Wildcards & Character Classes
Positional Anchors
^(Caret): Anchors match to the beginning of the line.^rootmatches lines starting withroot.$(Dollar): Anchors match to the end of the line.bash$matches lines ending withbash.^$: Matches lines with zero characters between start and end (empty/blank lines).^root$: Matches lines containing only the exact stringrootand nothing else.
Bracket Expressions (Character Sets)
Bracket expressions define character sets matching any single character contained within the brackets:
[abc]: Matches eithera,b, orc.[a-z]: Matches any lowercase alphabetic letter.[0-9]: Matches any numeric digit.[^abc]: Negation (Inverted Set) — Matches any single character excepta,b, orcwhen^is the first character inside the brackets.
POSIX Character Classes
POSIX defines locale-aware character class aliases that must be enclosed inside an outer set of brackets ([[:class:]]):
| POSIX Class | Equivalent Set | Matches |
|---|---|---|
[[:alnum:]] | [a-zA-Z0-9] | Alphanumeric characters (letters and digits) |
[[:alpha:]] | [a-zA-Z] | Alphabetic letters |
[[:digit:]] | [0-9] | Numeric digits |
[[:lower:]] | [a-z] | Lowercase alphabetic letters |
[[:upper:]] | [a-Z] | Uppercase alphabetic letters |
[[:space:]] | [ \t\n\r\f] | Whitespace characters (space, tab, newline, form feed) |
[[:blank:]] | [ \t] | Horizontal blank space (space and tab only) |
[[:punct:]] | [!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~] | Punctuation and symbol characters |
[[:xdigit:]] | [0-9a-fA-F] | Hexadecimal digits |
# Match any line containing a 3-digit number:
$ grep '[[:digit:]][[:digit:]][[:digit:]]' /var/log/syslog
3. The grep Family & Command-Line Flags
The GNU grep suite contains three command variants:
grep: Searches files using standard POSIX Basic Regular Expressions (BRE).egrep(orgrep -E): Searches files using Extended Regular Expressions (ERE).fgrep(orgrep -F): Searches for Fixed literal strings. It disables all regex parsing, making it extremely fast when searching for exact strings containing dots, brackets, asterisks, or dollar signs.
Essential grep Command-Line Flags
| Flag | Long Option | Operational Behavior |
|---|---|---|
-i | --ignore-case | Ignores case distinctions in both pattern and input data. |
-v | --invert-match | Inverts selection: outputs only lines that do NOT match the pattern. |
-c | --count | Suppresses normal output; prints only the numeric count of matching lines. |
-l | --files-with-matches | Prints only the names of files containing matches (stops after first match). |
-L | --files-without-match | Prints only the names of files that do NOT contain matches. |
-n | --line-number | Prefixes each output line with its 1-based line number within the file. |
-r / -R | --recursive | Recursively searches all directories (-R follows symlinks). |
-w | --word-regexp | Matches only whole words bounded by non-word characters. |
-x | --line-regexp | Matches only whole lines (pattern must match the entire line from start to end). |
-o | --only-matching | Prints only the exact matching segment of a line rather than the whole line. |
-E | --extended-regexp | Interprets pattern as Extended Regular Expression (ERE, equivalent to egrep). |
-F | --fixed-strings | Interprets pattern as literal text (Fixed strings, equivalent to fgrep). |
-A <N> | --after-context=<N> | Prints <N> lines of trailing context after each match. |
-B <N> | --before-context=<N> | Prints <N> lines of leading context before each match. |
-C <N> | --context=<N> | Prints <N> lines of output context both before and after each match. |
4. Practical Configuration & Log Filtering Recipes
Recipe 1: Stripping Comments and Blank Lines from Config Files
A quintessential system administration task tested on LPIC-1 is inspecting active configuration parameters while filtering out comment lines (starting with #) and empty lines:
# Method 1: Chaining standard grep commands:
$ grep -v '^#' /etc/ssh/sshd_config | grep -v '^$'
# Method 2: Single command using Extended Regular Expressions (ERE):
$ grep -Ev '^(#|$)' /etc/ssh/sshd_config
# Method 3: Handling leading whitespace before comment markers:
$ grep -Ev '^[[:space:]]*(#|$)' /etc/ssh/sshd_config
Input File (/etc/ssh/sshd_config): Filtered Output (`grep -Ev '^(#|$)'`):
┌───────────────────────────────────┐ ┌───────────────────────────────────┐
│ # OpenSSH Daemon Config │ │ Port 22 │
│ Port 22 │ │ PermitRootLogin no │
│ │ │ PasswordAuthentication yes │
│ # Security Settings │ └───────────────────────────────────┘
│ PermitRootLogin no │
│ PasswordAuthentication yes │
└───────────────────────────────────┘
Recipe 2: Matching IP Addresses with ERE
# Find IPv4 addresses in access logs using ERE interval quantifiers:
$ grep -E '([0-9]{1,3}\.){3}[0-9]{1,3}' /var/log/nginx/access.log
Recipe 3: Fast Fixed-String Search with fgrep
# Search for literal string '$USER[0]' without escaping metacharacters:
$ fgrep '$USER[0]' /opt/scripts/*.sh
# Or using grep -F:
$ grep -F '$USER[0]' /opt/scripts/*.sh
💡 LPIC-1 Exam Fill-in-the-Blank Alert: What
grepcommand option enables Extended Regular Expression (ERE) pattern interpretation? Answer:-E(or--extended-regexp)
An administrator needs to filter a configuration file to display only active directives, removing all blank lines and all lines that begin with a # comment symbol. Which command accomplishes this?
grep -i '^(#|$)' /etc/nginx/nginx.conf
grep -v '#$' /etc/nginx/nginx.conf
grep -E '^[^#]' /etc/nginx/nginx.conf
grep -Ev '^(#|$)' /etc/nginx/nginx.conf
An administrator needs to search log files for the literal string [ERROR] [192.168.1.1] without having to manually escape the square brackets or periods. Which utility should be used?
fgrep '[ERROR] [192.168.1.1]' /var/log/app.log
egrep '[ERROR] [192.168.1.1]' /var/log/app.log
grep -E '[ERROR] [192.168.1.1]' /var/log/app.log
grep -w '[ERROR] [192.168.1.1]' /var/log/app.log
Which of the following represents the correct Basic Regular Expression (BRE) syntax when using standard grep to match between 3 and 5 consecutive digits?
[0-9]{3,5}
[0-9]\{3,5\}
[[:digit:]](3,5)
[0-9]+{3,5}
Sections you finish are checked off in the contents.