Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 4

Filtering Text with Grep and Regular Expressions

Recommended resources

In our last session, you mastered using grep to find exact words and phrases, a fundamental skill for sifting through data. However, in Capture The Flag challenges, the information you seek—like flags, credentials, or IP addresses—often follows a specific pattern rather than being a simple, predictable string. To find this kind of data, you need to move beyond literal searches and learn the language of patterns: regular expressions.

This lesson will unlock the true power of grep by teaching you how to construct basic regular expressions (regex). You will learn the core syntax for defining patterns, allowing you to match character sets, specify repetitions, and create flexible searches that can find precisely what you're looking for, even when you don't know the exact text. This is a critical step in elevating your command-line skills from basic usage to sophisticated data analysis, which is essential for success in CTFs.

Basic vs. Extended Regular Expressions

Before we dive into writing patterns, it's important to understand that grep can interpret a few different "dialects" of regular expressions. The two main ones are Basic Regular Expressions (BRE) and Extended Regular Expressions (ERE).

  • Basic (BRE): This is grep's default mode. It's older, and many special characters like ?, +, |, and () are treated as normal characters unless you "escape" them with a backslash (\). This can make your patterns look cluttered and harder to read (e.g., $fear$\?less).
  • Extended (ERE): You activate this mode with the -E flag (grep -E) or by using the egrep command (which is just an alias for grep -E). In this mode, those same special characters have their pattern-matching meaning by default, leading to cleaner, more intuitive expressions (e.g., (fear)?less).

For our purposes, and for most modern use cases, it is highly recommended to use Extended Regular Expressions (grep -E). It makes your commands more readable and powerful without extra syntax. Throughout this lesson, all examples will assume you are using grep -E.

The article "Regular Expressions in Grep" from Linuxize provides a clear distinction between these syntaxes right at the beginning.

Regular Expressions in Grep (Regex)

This article clearly explains the different regular expression syntaxes supported by grep.

Please read the introduction and the section Grep Regular Expression Syntax. Pay close attention to the table-like breakdown of BRE, ERE, and PCRE. This will solidify why we are choosing to use -E.


The Building Blocks of Regex

Regular expressions are built from a combination of literal characters (like a, b, 1, 2) and special characters called meta-characters, which define the rules of the pattern. Let's explore the most important ones.

The tutorial from DigitalOcean, "Mastering grep with Regular Expressions," will be our main guide. It provides clear explanations and examples for each concept.

Anchors and Wildcards: ^, $, and .

Anchors don't match characters themselves but rather positions in the text. The wildcard matches any character.

  • ^: Matches the beginning of a line.
  • $: Matches the end of a line.
  • .: Matches any single character.

These are fundamental for filtering structured files. For example, in a configuration file, you might want to find lines that start with user= to find usernames, or in a log file, you might search for login..failed to find login: failed and login failed.

Mastering grep with Regular Expressions for Efficient Text ...

This tutorial provides excellent, step-by-step instructions for building regular expressions.

Start by reading the sections on Anchor Matches and Matching Any Character. These sections cover the ^, $, and . meta-characters.

Character Sets and Ranges: [...]

Character sets, or bracket expressions, are one of the most powerful features of regex. They allow you to specify a list or range of characters that can match at a single position.

  • [abc]: Matches either a, b, or c.
  • [a-z]: Matches any lowercase letter.
  • [0-9]: Matches any digit.
  • [^abc]: The ^ inside brackets negates the set, matching any character that is not a, b, or c.

In CTFs, you'll often see flags with a specific format, like flag{...} where the content is alphanumeric. A pattern like flag{[a-z0-9_]} would match flag{ followed by any single lowercase letter, digit, or underscore.

Mastering grep with Regular Expressions for Efficient Text ...

Now, continue in the same article with the section on Bracket Expressions.

Read the part titled Bracket Expressions. This covers defining sets, negating them with ^, and using ranges like [A-Z]. It also introduces POSIX character classes (e.g., [[:digit:]]), which are a more portable way to specify common ranges.

Quantifiers, Grouping, and Alternation: +, *, ?, {}, (), |

This is where Extended Regular Expressions (-E) really shine. These meta-characters allow you to control repetition, group parts of your pattern, and specify alternatives.

  • Quantifiers: Define how many times the preceding element can occur.
    • +: One or more times.
    • *: Zero or more times.
    • ?: Zero or one time (makes it optional).
    • {n}: Exactly n times.
    • {n,m}: Between n and m times.
  • Grouping (): Groups a sub-pattern, allowing you to apply a quantifier to the whole group.
  • Alternation |: Acts as a logical "OR" between expressions, usually inside a group.

Let's combine these. The regex (error|warn|fail) would find lines containing "error" OR "warn" OR "fail". A classic CTF task is extracting IP addresses from a log file. An IP address is four numbers (0-255) separated by dots. A simple regex for this could be:
[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}

Notice the \.. Since . is a meta-character (wildcard), we must escape it with a backslash (\) to match a literal dot.

This terminal output shows a practical use of `egrep` (which is the same as `grep -E`). The command `egrep '192.168.2.(13|18)'` uses grouping `()` and alternation `|` to find lines containing either `192.168.2.13` or `192.168.2.18`, demonstrating the power of Extended Regular Expressions.

Now, let's turn back to the DigitalOcean article to see these concepts explained in detail.

Mastering grep with Regular Expressions for Efficient Text ...

This is the core of the lesson, where you'll learn the syntax that makes grep -E so powerful.

First, quickly read the section Escaping Meta-Characters to understand the purpose of the backslash (\). Next, read the entire section on Extended Regular Expressions. This is crucial as it covers Grouping (), Alternation |, Quantifiers ? and +, and specifying repetitions with {}.


A Visual Summary and Reference

Regular expressions can be dense, and having a good reference is invaluable. The following cheatsheet provides a fantastic overview of the grep command and the regex syntax we've discussed. It's a great resource to save for future use.

This cheatsheet visually summarizes `grep` usage, options, and the various regular expression components like wildcards, quantifiers, character classes, and anchors. It's an excellent reference for constructing patterns.

To see these concepts demonstrated in a practical, hands-on way, the following video provides a great walkthrough.

Regular Expressions in Linux | Intro to GREP and RegEx | RegEx Tutorial

This video from KodeKloud demonstrates the core regex concepts with clear, command-line examples.

Watch the following segments to see these patterns in action: Basic matching, covering anchors, the . wildcard, and the * quantifier. Meta-characters, where the presenter explains character sets [], negation [^...], alternation |, and escaping \. Quantifiers, focusing on using {} to specify exact or ranges of repetitions. You can optionally watch the final part on real-world uses, which shows how to apply these patterns to system log files.


Conclusion

In this lesson, you've taken your grep skills to the next level. You've learned that regular expressions are a powerful language for describing patterns, and you now know the fundamental building blocks to create them. We covered the difference between Basic and Extended Regex, advocating for grep -E for its cleaner syntax. You can now use anchors (^, $), wildcards (.), character sets ([]), quantifiers (+, *, ?, {}), grouping (), and alternation | to construct sophisticated searches. These skills are not just theoretical; they are the bread and butter of text processing on the command line and will be indispensable as you analyze files in CTF challenges.

You can now build powerful one-line commands to extract complex data from any text stream. But what if you need to run a series of these commands repeatedly? In our next lesson, we will introduce shell scripting, which will allow you to automate these tasks and build your own custom tools.