Regular Expressions: Patterns for grep

Patterns, not just words

Often you don't know the exact text, only its shape: a line that starts with Server, three digits, a dash, four digits. A regular expression (regex) describes that shape. grep understands them, and grep -E (extended) understands the full set.

cat contacts.txt

In the terminal

student@vulntech:~$ cat contacts.txt
Ada Lovelace, ada@example.com, 555-0101
Grace Hopper, grace.hopper@navy.example, 555-0102
Linus, linus@kernel.example, call 555-0199
not an email: bob(at)example.com
Server 10.0.0.15 is up
Server 192.168.1.30 is down
Order #4471 shipped
order #12 cancelled

The building blocks

SymbolMeansExample
^Start of the line^Server
$End of the lineshipped$
.Any one characterh.t matches hat, hot, h t
[abc]One of these characters[Oo]rder
[0-9], [a-z]One character from a range[0-9] is any digit
[^0-9]Any character except theseNot a digit
*The thing before it, 0 or more timeslo*l: ll, lol, lool
+1 or more times (-E)[0-9]+: a number
?0 or 1 time (-E)colou?r
{3}Exactly 3 times (-E)[0-9]{3}
a|ba or b (-E)Ada|Linus
\bA word boundary: the edge of a word\bcat\b doesn't match concat
\.A real dot (the backslash cancels the special meaning)10\.0

Anchors: start and end

grep '^Server' contacts.txt
grep 'shipped$' contacts.txt
grep -i '^order' contacts.txt

In the terminal

student@vulntech:~$ grep '^Server' contacts.txt
Server 10.0.0.15 is up
Server 192.168.1.30 is down
student@vulntech:~$ grep 'shipped$' contacts.txt
Order #4471 shipped
student@vulntech:~$ grep -i '^order' contacts.txt
Order #4471 shipped
order #12 cancelled

Classes and repeats

Find phone numbers: three digits, a dash, four digits. -o prints only the part that matched instead of the whole line:

grep -E '[0-9]{3}-[0-9]{4}' contacts.txt
grep -oE '[0-9]{3}-[0-9]{4}' contacts.txt

In the terminal

student@vulntech:~$ grep -E '[0-9]{3}-[0-9]{4}' contacts.txt
Ada Lovelace, ada@example.com, 555-0101
Grace Hopper, grace.hopper@navy.example, 555-0102
Linus, linus@kernel.example, call 555-0199
student@vulntech:~$ grep -oE '[0-9]{3}-[0-9]{4}' contacts.txt
555-0101
555-0102
555-0199

An email address is letters, dots and so on, an @, then a domain with a dot in it:

grep -oE '[a-z.]+@[a-z]+\.[a-z.]+' contacts.txt

In the terminal

student@vulntech:~$ grep -oE '[a-z.]+@[a-z]+\.[a-z.]+' contacts.txt
ada@example.com
grace.hopper@navy.example
linus@kernel.example

IP addresses: four numbers separated by real dots, and alternatives with |:

grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' contacts.txt
grep -E 'Ada|Linus' contacts.txt

In the terminal

student@vulntech:~$ grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' contacts.txt
10.0.0.15
192.168.1.30
student@vulntech:~$ grep -E 'Ada|Linus' contacts.txt
Ada Lovelace, ada@example.com, 555-0101
Linus, linus@kernel.example, call 555-0199

Tip: Always put the pattern in single quotes. Without them, the shell treats *, $ and | as its own special characters before grep sees them.

Common mistake: Wildcards (module 3) and regular expressions look alike but aren't the same. In a file name, *.txt means anything ending in .txt. In a regex, * means repeat the thing before me, and . means any character.

Remember: ^ start, $ end, . any character, [ ] one of, * + ? {n} repeats. Use grep -E and single quotes.

HOME LEARN COMMUNITY DASHBOARD
Practice terminal Starting…