Mastering Regex in Linux: A Comprehensive Guide

Regular expressions (regex) in Linux are powerful tools used for pattern matching within text. They allow users to search, match, and manipulate text using specific patterns of characters. Regular expressions are integral to many commands like grep, sed, awk, and vi. Linux uses two primary types of regular expressions: Basic Regular Expressions (BRE) and Extended Regular Expressions (ERE), which differ slightly in their syntax and available operators.

In this detailed explanation, we’ll cover the concept of regular expressions, common regex commands, metacharacters, and practical examples.


Basic and Extended Regular Expressions

  • Basic Regular Expressions (BRE): This is the default type of regular expression in Linux, and it’s simpler. For example, grep uses BRE by default.
  • Extended Regular Expressions (ERE): EREs allow for more advanced regex patterns, and commands like egrep or grep -E use ERE by default. The sed -r and awk commands also support ERE.

Although the two types of regular expressions differ, most of the same principles apply to both. The major difference lies in how metacharacters (special symbols used for pattern matching) are interpreted.


Metacharacters in Regular Expressions

Regular expressions are built using metacharacters. Metacharacters have special meanings and allow for complex pattern matching. Below is a breakdown of the most commonly used metacharacters:

1. Dot (.)

The dot matches any single character except for a newline (\n).

  • Example:
Bash
  grep 'h.t' file.txt

This will match “hat”, “hit”, “hot”, etc., in file.txt.

2. Caret (^)

The caret matches the start of a line.

  • Example:
Bash
  grep '^Error' file.txt

This will match any line that starts with “Error”.

3. Dollar Sign ($)

The dollar sign matches the end of a line.

  • Example:
Bash
  grep 'log$' file.txt

This will match lines that end with the word “log”.

4. Asterisk (*)

The asterisk matches zero or more occurrences of the preceding character.

  • Example:
Bash
  grep 'go*gle' file.txt

This will match “ggle”, “gogle”, “google”, “gooogle”, etc.

5. Plus (+) (Extended Regex Only)

The plus matches one or more occurrences of the preceding character.

  • Example (with grep -E for extended regex):
Bash
  grep -E 'go+gle' file.txt

This will match “gogle”, “google”, “gooogle”, etc., but not “ggle”.

6. Question Mark (?)

The question mark matches zero or one occurrence of the preceding character. It makes the preceding character optional.

  • Example:
Bash
  grep -E 'colou?r' file.txt

This will match both “color” and “colour”.

7. Square Brackets ([])

Square brackets match any one of the enclosed characters. You can also specify ranges of characters using hyphens.

  • Examples:
  • grep '[aeiou]' file.txt: Matches any line that contains a vowel.
  • grep '[0-9]' file.txt: Matches any line containing a digit.
  • grep '[a-z]' file.txt: Matches any lowercase letter.
  • grep '[A-Za-z]' file.txt: Matches any uppercase or lowercase letter.

8. Negated Character Class ([^])

If you place a caret (^) inside square brackets at the beginning, it negates the character class, meaning it will match any character except those specified.

  • Example:
Bash
  grep '[^aeiou]' file.txt

This will match any character that is not a vowel.

9. Curly Braces ({})

Curly braces specify repetitions of the preceding character or group.

  • Examples:
  • grep -E 'a{3}' file.txt: Matches “aaa”.
  • grep -E 'a{2,4}' file.txt: Matches “aa”, “aaa”, or “aaaa” (between 2 and 4 occurrences).
  • grep -E 'a{2,}' file.txt: Matches “aa”, “aaa”, “aaaa”, etc. (2 or more occurrences).

10. Pipe (|)

The pipe operator performs a logical OR between patterns. It’s used to match one pattern or another.

  • Example (with grep -E for extended regex):
Bash
  grep -E 'error|failure' file.txt

This will match lines containing either “error” or “failure”.

11. Parentheses (())

Parentheses are used for grouping expressions. They group patterns that you want to treat as a single unit.

  • Example:
Bash
  grep -E '(ab|cd){2}' file.txt

This matches two repetitions of either “ab” or “cd”, like “abab”, “cdcd”, “abcd”, or “cdab”.

12. Backslash (\)

The backslash is used to escape a metacharacter, treating it as a literal character rather than a special one.

  • Example:
Bash
  grep '\.' file.txt

This matches a literal dot (.) instead of using the dot as a metacharacter.

13. Word Boundaries (\b)

\b represents a word boundary, ensuring that the pattern matches at the beginning or end of a word.

  • Example:
Bash
  grep '\berror\b' file.txt

This matches the word “error” but not words like “errors” or “supererror”.


Types of Regular Expressions

1. Basic Regular Expressions (BRE)

BRE uses simple patterns where most metacharacters like +, ?, |, and {} need to be escaped with a backslash (\) to be used as metacharacters.

  • Examples:
  • To match one or more occurrences of “a”, you use:
    bash grep 'a\+' file.txt
  • To match any line that starts with “Hello” and ends with a number:
    bash grep '^Hello.*[0-9]$' file.txt

2. Extended Regular Expressions (ERE)

ERE, supported by grep -E, egrep, sed -E, and awk, offers more advanced pattern matching and does not require escaping metacharacters like +, ?, |, and {}.

  • Examples:
  • Match one or more occurrences of “a” without escaping:
    bash grep -E 'a+' file.txt
  • Match any line that contains “abc” followed by either “123” or “456”:
    bash grep -E 'abc(123|456)' file.txt

Practical Examples of Regular Expressions

1. Matching Lines That Start with a Word

Bash
grep '^The' file.txt

This matches lines that start with the word “The”.

2. Find Lines Ending with a Number

Bash
grep '[0-9]$' file.txt

This matches lines that end with a digit (0-9).

3. Search for IP Addresses

Bash
grep -Eo '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' logfile.txt

This extracts IP addresses (in the format xxx.xxx.xxx.xxx) from logfile.txt.

4. Find Empty Lines in a File

Bash
grep '^$' file.txt

This finds all empty lines in file.txt.

5. Find Lines That Contain Only Numbers

Bash
grep '^[0-9]\+$' file.txt

This matches lines that consist of only digits (one or more digits).

6. Matching a Phone Number Pattern

To match a U.S. phone number in the format (123) 456-7890, you can use:

Bash
grep -E '\([0-9]{3}\) [0-9]{3}-[0-9]{4}' file.txt

7. Extracting Words with awk and Regex

Bash
awk '/\bLinux\b/' file.txt

This finds lines containing the word “Linux” as a whole word using word boundaries (\b).


Advanced Usage with sed, awk, and Other Tools

Regular expressions are used extensively with other Linux commands like sed (stream editor) and awk (text processing tool).

1. Using Regex in sed

  • Replace the word “foo” with “bar” in a file:
Bash
  sed 's/foo/bar/g' file.txt
  • Delete lines containing

Regular expressions (regex) in Linux are a powerful tool for pattern matching in text. They are not a standalone command, but are often used with commands such as grep, sed, awk, find, perl, vim, and others. Regular expressions enable complex pattern matching and text manipulation.

Linux regular expressions come in two types:

  • Basic Regular Expressions (BRE), which are typically used by tools like grep by default.
  • Extended Regular Expressions (ERE), which offer more expressive power and are used by adding flags like -E to grep or directly in tools like egrep.

Here is a detailed explanation of regular expressions, their syntax, and how they can be used effectively in Linux.


1. Basic Components of Regular Expressions

Regular expressions are made up of metacharacters (special characters with specific meanings) and literals (normal characters). By combining metacharacters and literals, you can create powerful search patterns.

a) Literals

A literal is any standard character that matches itself. For example:

  • The regular expression apple will match any instance of “apple” in a text.

b) Metacharacters

Metacharacters are characters with special meanings in regex. They enable more powerful pattern matching.

Here’s a list of common regex metacharacters:

MetacharacterMeaning
.Matches any single character (except newline)
^Matches the start of a line
$Matches the end of a line
*Matches zero or more occurrences of the preceding character
+Matches one or more occurrences of the preceding character
?Matches zero or one occurrence of the preceding character
[]Matches any one of the characters enclosed in brackets (character class)
[^]Matches any character except the ones enclosed in brackets
|Alternation, matches either the pattern on the left or the right of the |
()Groups patterns together

Example:

Bash
grep "a.e" file.txt

This will match any three-character sequence that starts with “a” and ends with “e”, with any single character in between (like “ape”, “ace”, etc.).


2. Anchors

Anchors are used to match positions in text, rather than characters.

a) Start of Line (^)

The ^ symbol matches the beginning of a line.

Bash
grep "^hello" file.txt

This will match lines that start with “hello”.

b) End of Line ($)

The $ symbol matches the end of a line.

Bash
grep "world$" file.txt

This will match lines that end with “world”.

Example:

To match lines that begin with “apple” and end with “juice”:

Bash
grep "^apple.*juice$" file.txt

3. Character Classes

Character classes define sets of characters that you want to match. They are written in square brackets ([]).

a) Basic Character Classes

  • [abc]: Matches any one of the characters a, b, or c. Example:
Bash
  grep "[aeiou]" file.txt

This will match any line containing a vowel.

b) Character Ranges

You can specify ranges of characters using a dash (-). For example:

  • [a-z]: Matches any lowercase letter from a to z.
  • [0-9]: Matches any digit.

Example:

Bash
grep "[0-9]" file.txt

This matches any line containing a digit.

c) Negated Character Classes

If you want to match any character except those in the class, use [^].

Example:

Bash
grep "[^a-zA-Z]" file.txt

This matches lines containing any non-alphabetical character.

d) Predefined Character Classes

Predefined character classes make it easier to work with commonly used character sets.

  • \d: Matches any digit (equivalent to [0-9]).
  • \D: Matches any non-digit.
  • \w: Matches any word character (letters, digits, and underscores) (equivalent to [a-zA-Z0-9_]).
  • \W: Matches any non-word character.
  • \s: Matches any whitespace character (spaces, tabs, newlines).
  • \S: Matches any non-whitespace character.

In Linux, you might need to escape these classes (like \\d for digits) depending on the tool you’re using.

Example:

Bash
grep "\d" file.txt

This will match any line that contains a digit (note the escaped \ in Linux).


4. Quantifiers

Quantifiers specify how many times the preceding character or group should be matched.

a) Asterisk (*)

The * matches zero or more occurrences of the preceding element.

Bash
grep "lo*ng" file.txt

This matches “lng”, “long”, “loooong”, etc.

b) Plus (+)

The + matches one or more occurrences of the preceding element (Extended Regular Expression).

Bash
grep -E "lo+ng" file.txt

This matches “long”, “loong”, etc., but not “lng”.

c) Question Mark (?)

The ? matches zero or one occurrence of the preceding element.

Bash
grep -E "colo?ur" file.txt

This matches both “color” and “colour”.

d) Curly Braces ({})

Curly braces are used to specify a specific number of occurrences or a range.

  • {n}: Exactly n occurrences.
  • {n,}: At least n occurrences.
  • {n,m}: Between n and m occurrences.

Example:

Bash
grep -E "a{3}" file.txt

This matches “aaa”, but not “aa” or “aaaa”.


5. Grouping and Alternation

a) Grouping (())

Parentheses are used to group parts of a regex together. Grouping allows you to apply quantifiers to entire patterns or use them in combination with alternation.

Example:

Bash
grep -E "(ab)+" file.txt

This matches one or more occurrences of “ab” (like “ababab”).

b) Alternation (|)

The | symbol acts as a logical OR, allowing you to match one pattern or another.

Bash
grep -E "cat|dog" file.txt

This matches lines that contain either “cat” or “dog”.

Example with grouping:

Bash
grep -E "(cat|dog)house" file.txt

This matches either “cathouse” or “doghouse”.


6. Escape Characters (\)

Many metacharacters like . and * have special meanings. If you want to search for the literal character, you need to escape it with a backslash (\).

Example:

Bash
grep "\." file.txt

This searches for a literal period (.), rather than treating it as a wildcard.


7. Regular Expression Examples

a) Search for Lines Containing Email Addresses

Bash
grep -E "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}" file.txt

This searches for email addresses in file.txt. It looks for the following pattern:

  • [a-zA-Z0-9._%+-]+: One or more valid characters before the “@” symbol.
  • @: The “@” symbol.
  • [a-zA-Z0-9.-]+: One or more characters for the domain name.
  • \.[a-zA-Z]{2,}: A dot followed by a two-letter or longer domain extension (e.g., “.com”, “.org”).

b) Search for Lines Containing a Valid IP Address

Bash
grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" file.txt

This matches valid IP addresses with the following pattern:

  • ([0-9]{1,3}\.){3}: Three numbers (1 to 3 digits) followed by a period.
  • [0-9]{1,3}: A final group of 1 to 3 digits.

c) Find Lines Starting with a Digit

Bash
grep "^[0-9]" file.txt

This matches lines that start with a digit.

d) Search for Repeated Words

Bash
grep -E "\b([a-zA-Z]+) \1\b" file.txt

This matches repeated words in file.txt. For example, it would match “the the” or “dog dog”.


8. Tools Supporting Regular Expressions

Regular expressions are supported by many Linux tools:

  • grep: The most common text searching tool.
  • grep for basic regex (BRE).
  • `grep -E

Share
OpenLib .

OpenLib .

The Founder - OpenLib.io

You may also like...