Last modified: August 05, 2024

This article is written in: 🇺🇸

The grep Command

The grep command is a powerful tool used in Unix-based systems for searching and filtering text. Its name stands for "global regular expression print". grep is primarily used to search text or files for lines that match a certain pattern.

Here's an example of basic grep usage. To search for the word "key" in a file called file_name.txt, you can use the following command:

grep 'key' file_name.txt

This command will output all lines in file_name.txt that contain the word 'key'.

User
 |
 | Uses 'grep' with arguments (pattern & file)
 v
+-------------------------------+
| grep Command                  |
|  - Reads File                 |
|  - Matches Lines with Pattern |
+-------------------------------+
 |
 | Outputs matching lines
 v
Terminal/Shell

Common Options for grep

The grep command includes various options, or "flags," that modify its behavior. Below are some commonly used flags:

Flag Description
-c Counts and prints the number of lines that match the pattern.
-i Makes the search case-insensitive.
-r Recursively searches directories for the pattern.
-v Inverts the search, displaying lines that do not match the pattern.
-n Displays the line numbers along with the lines that match the pattern.
-e Allows specifying multiple patterns for grep to search.
-E Enables the use of extended regular expressions, allowing operators like +, ?, and \| without escaping them.
-l Lists the filenames that contain the matching pattern.
--color Highlights the matching strings in the output.

Using the -e Flag

To search for either 'pattern1' or 'pattern2' in a file:

grep -e 'pattern1' -e 'pattern2' file_name

Suppose the file file_name contains the following lines:

This is a line containing abc.
This is another line with def.
This line does not contain either pattern.

To find lines containing either 'abc' or 'def', use:

grep -e 'abc' -e 'def' file_name

Output:

This is a line containing abc.
This is another line with def.

Using Extended Regular Expressions with -E

For more advanced pattern matching, use regular expressions. For example, to find lines containing either 'abc' or 'def':

grep -E 'a(bc|def)' file_name

Recursive Search with -r

To search for a string across all files and directories starting from the current directory:

grep -r '192.45.92.0' *

Explanation:

Example Output:

If log.txt contains the line Connecting to server at 192.45.92.0, the output will be:

log.txt:Connecting to server at 192.45.92.0

This indicates that the string 192.45.92.0 was found in log.txt, along with the line where it was found.

Using -l Flag

To find all files containing the word 'nginx' in the /var/log/ directory:

grep -l 'nginx' /var/log/*

If the directory contains access.log with the word 'nginx', the output will be:

/var/log/access.log

Using -v Flag to Exclude Patterns

To exclude comment and empty lines from the SSH configuration file:

grep -v ^# /etc/ssh/sshd_config | grep -v ^$

If the file contains commented lines and empty lines, this command will filter them out, displaying only active configuration lines.

Using -E Flag with Extended Regular Expressions

To exclude comment and empty lines using a single command with extended regular expressions:

grep -EV "^(#|$)" /etc/ssh/sshd_config

This command achieves the same result as using grep -v ^# | grep -v ^$ but in a more concise way.

To search for the IP address 10.0.0.1 in all files under /var/log/, ignoring case sensitivity:

grep -ri '10.0.0.1' /var/log/ 2> /dev/null

If the IP address appears in multiple log files, the output will list each occurrence along with the file name and line content.

Matching Group Names in /etc/group

To search for lines in the /etc/group file containing 'rw.':

grep 'rw.' /etc/group

This will list all group entries with 'rw.' in their name or properties.

Highlighting Matching Patterns

To highlight numeric user IDs in the /etc/group file:

grep --color ':[0-9]*:' /etc/group

This command will highlight numeric sequences, typically representing user IDs, in the output.

Understanding Regular Expressions

Regular expressions (RegEx) are versatile tools used for defining search patterns, making them useful in text manipulation and retrieval. They are commonly utilized in various programming and scripting languages, not just with grep. Here's an overview of some essential RegEx symbols:

Symbol Description
. 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 or group
\ Escapes the next character, nullifying any special meaning it may have
() Groups several characters as a single unit, also used to capture groups
? Matches zero or one occurrence of the preceding character or group

Using ^ (Start of Line)

To find all lines in a file that begin with the character #:

grep '^#' /opt/test.txt

This will match lines like # This is a comment.

Using $ (End of Line)

To search for lines that end with the string 'xxx':

grep 'xxx$' /opt/test.txt

This matches lines like This is a line with xxx.

Using . (Any Character)

To find lines containing "a" followed by any character and then "c":

grep 'a.c' /opt/test.txt

This matches "abc", "a-c", "a3c", etc., but not "ac".

Using \ (Escape Character)

To search for a literal dot . in the text, you must escape it:

grep '\.' /opt/test.txt

This matches lines containing a period, such as "This is a line."

Using () (Grouping)

To capture groups or apply operators to a group of characters:

grep '\(abc\)*' /opt/test.txt

This searches for zero or more occurrences of the sequence "abc".

Using ? (Zero or One)

To find lines containing "color" or "colour":

grep 'colou?r' /opt/test.txt

This matches both "color" and "colour".

Using Character Classes

To find lines containing either 'abc' or 'abz':

grep 'ab[cz]' /opt/test.txt

This matches lines with "abc" or "abz", as [cz] specifies either 'c' or 'z'.

RegEx Quantifiers

Quantifiers in regular expressions specify how many times an element (character, group, or character class) must appear for a match to be successful.

Symbol Description
* Matches zero or more occurrences of the preceding element
? Matches zero or one occurrence of the preceding element (optional)
+ Matches one or more occurrences of the preceding element
{n} Matches exactly n occurrences of the preceding element
{n,} Matches n or more occurrences of the preceding element
{,m} Matches up to m occurrences of the preceding element
{n,m} Matches at least n and at most m occurrences of the preceding element

Using * (Zero or More)

To find lines containing "hello" followed by any number of "o"s:

grep -E 'hello*' file_name

This will match "hell", "hello", "helloooo", etc.

Using ? (Zero or One)

To find lines containing "color" or "colour":

grep -E 'colou?r' file_name

This matches both "color" and "colour".

Using + (One or More)

To find lines containing one or more digits:

grep -E '[0-9]+' file_name

This matches "1", "123", "42", etc.

Using {n} (Exactly n)

To find lines containing exactly three consecutive digits:

grep -E '[0-9]{3}' file_name

This matches "123", "456", but not "12" or "1234".

Using {n,} (n or More)

To find lines containing at least two vowels in a row:

grep -E '[aeiou]{2,}' file_name

This matches "ooze", "queue", but not "hat" or "red".

Using {,m} (Up to m)

To find lines with at most three consecutive letters "a":

grep -E 'a{,3}' file_name

This matches "a", "aa", "aaa", but not "aaaa".

Using {n,m} (Between n and m)

To find words containing between 4 to 6 alphabetic characters:

grep -E '\b[[:alpha:]]{4,6}\b' file_name

This matches words like "word", "hello", "grep", but not "a" or "complex".

Challenges

  1. Enumerate the visible files and directories within the current working directory. However, do not include those that are hidden or contain the word "test" in their name.
  2. Track down all the commands involving the word "clone" that have been executed in the last week. Bear in mind that command-line histories vary depending on the shell and user configurations.
  3. Validate the existence of a user named "adam" in the system. If such a user is found, return information about their home directory and their default shell. Be aware that user information may be stored in different ways based on the system configuration.
  4. In a file named file.txt, locate and count the number of lines containing the word "apple".
  5. In the same file.txt, identify all lines containing the pattern [A-Z]{3}. Then convert these lines into uppercase. This requires a combination of regular expressions and text transformation.

Table of Contents

    The grep Command
    1. Common Options for grep
      1. Using the -e Flag
      2. Using Extended Regular Expressions with -E
      3. Recursive Search with -r
      4. Using -l Flag
      5. Using -v Flag to Exclude Patterns
      6. Using -E Flag with Extended Regular Expressions
      7. Case-Insensitive Recursive Search
      8. Matching Group Names in /etc/group
      9. Highlighting Matching Patterns
    2. Understanding Regular Expressions
      1. Using ^ (Start of Line)
      2. Using $ (End of Line)
      3. Using . (Any Character)
      4. Using \ (Escape Character)
      5. Using () (Grouping)
      6. Using ? (Zero or One)
      7. Using Character Classes
    3. RegEx Quantifiers
      1. Using * (Zero or More)
      2. Using ? (Zero or One)
      3. Using + (One or More)
      4. Using {n} (Exactly n)
      5. Using {n,} (n or More)
      6. Using {,m} (Up to m)
      7. Using {n,m} (Between n and m)
    4. Challenges