Introduction
In this lab, you will learn how to effectively search for text within files on a Linux system using the powerful grep command. You will start by performing basic searches for specific strings in both single and multiple files, understanding how grep displays matching lines and identifies the source file when searching across several locations.
Building on this foundation, you will explore more advanced features to refine your searches. You will learn to display line numbers for context, use anchors like ^ and $ to match patterns at the beginning or end of a line, and harness the capabilities of both basic and extended regular expressions to perform complex and flexible pattern matching.
Perform a Basic Search in Files with grep
In this step, you will learn the fundamental usage of the grep command to perform basic searches within files. The grep (Global Regular Expression Print) command is a powerful command-line utility used to search for a specific string or pattern in one or more files and display the lines that contain it.
The basic syntax for grep is: grep PATTERN [FILE...]
Let's start with a simple task: finding information about our current user, labex, in the system's user database file. This information is stored in the /etc/passwd file.
Execute the following command in your terminal to find any lines containing the string labex in the /etc/passwd file:
grep labex /etc/passwd
You should see an output line from the file that contains your username, labex.
labex:x:5000:5000::/home/labex:/usr/bin/zsh
The grep command can also search across multiple files simultaneously. We will now search for the string labex in three important system configuration files: /etc/passwd, /etc/shadow (which stores secure user account information), and /etc/group (which defines user groups).
Since the /etc/shadow file contains sensitive information, you need administrative privileges to read it. You can use the sudo command to execute grep with these privileges. The labex user is configured with passwordless sudo access.
Execute the following command to search for labex in all three files:
sudo grep labex /etc/passwd /etc/shadow /etc/group
Notice that when searching in multiple files, grep prefixes each matching line with the name of the file where the match was found.
/etc/passwd:labex:x:5000:5000::/home/labex:/usr/bin/zsh
/etc/shadow:labex:$y$j9T$L6UYJUCu2XytrdFToEOw.1$yp2xAOVTbIPmbABMnS/xDsyce7xayU80JgIs3lrqw4B:20265:0:99999:7:::
/etc/group:sudo:x:27:labex
/etc/group:ssl-cert:x:121:labex
/etc/group:labex:x:5000:
/etc/group:public:x:5002:labex
This shows you all the lines across these three files that are related to the user labex.
Display Line Numbers with the -n Option
In this step, you will learn how to enhance the output of grep by displaying the line numbers where matches are found. This is particularly useful when you need to locate a pattern within a large file for editing or further analysis. The -n option tells grep to prefix each line of output with its corresponding line number from the input file.
Let's build upon the command from the previous step. You searched for the user labex across three system files. Now, you will perform the same search but also display the line numbers for each match.
Add the -n option to the command you executed in the previous step. Remember to use sudo as you are still accessing the restricted /etc/shadow file.
Execute the following command in your terminal:
sudo grep -n labex /etc/passwd /etc/shadow /etc/group
You will see a similar output to before, but now each line is preceded by the filename and the line number where the match occurred, separated by colons.
/etc/passwd:32:labex:x:5000:5000::/home/labex:/usr/bin/zsh
/etc/shadow:32:labex:$y$j9T$L6UYJUCu2XytrdFToEOw.1$yp2xAOVTbIPmbABMnS/xDsyce7xayU80JgIs3lrqw4B:20265:0:99999:7:::
/etc/group:21:sudo:x:27:labex
/etc/group:60:ssl-cert:x:121:labex
/etc/group:61:labex:x:5000:
/etc/group:62:public:x:5002:labex
Notice the numbers like 32, 32, 21, 60, 61, and 62 in the output. These are the line numbers. For example, the string labex was found on line 32 of /etc/passwd and line 32 of /etc/shadow. This simple option makes grep an even more effective tool for navigating and understanding file contents.
Match Line Position with ^ and $ Anchors
In this step, you will advance your grep skills by learning to use anchors. Anchors are special characters in regular expressions that don't match characters, but rather positions within a line. This allows you to create more specific and powerful search patterns. The two most common anchors are:
^(caret): Matches the beginning of a line.$(dollar sign): Matches the end of a line.
Let's see how these work using the /etc/passwd file.
First, consider a simple search for the string root in /etc/passwd:
grep root /etc/passwd
You might get multiple lines in the output, as other entries could contain the string "root".
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
Now, let's refine this. In the /etc/passwd file, the first field of each record is the username. To find the user record specifically for the user root, you can anchor your search to the beginning of the line using ^.
Execute the following command. The pattern ^root tells grep to only match lines that start with root.
grep ^root /etc/passwd
This time, the output is much more specific, showing only the line for the root user.
root:x:0:0:root:/root:/bin/bash
Next, let's use the end-of-line anchor, $. The last field in an /etc/passwd record specifies the user's default login shell. We can use this to find all users who have /bin/bash as their default shell.
The pattern bash$ will match any line that ends with the string bash.
grep bash$ /etc/passwd
This command will display all user entries where /bin/bash is the assigned shell.
root:x:0:0:root:/root:/bin/bash
(Note: Your output may vary if other users on the system also use bash as their default shell.)
By using ^ and $ anchors, you can significantly narrow down your search results to find exactly what you're looking for.
Match Patterns with Basic Regular Expressions
In this step, you'll explore how to use Basic Regular Expressions (BRE) with grep to create more flexible search patterns. In BRE, certain characters, called metacharacters, have special meanings that go beyond their literal value. This allows you to match patterns, not just fixed strings.
We will explore two fundamental metacharacters: * (asterisk) and . (dot).
First, let's examine the asterisk (*). This metacharacter matches the character immediately preceding it zero or more times. To see this in action, execute the following command. We'll enclose the pattern in single quotes ('roo*') to ensure the shell treats it as a literal pattern and doesn't try to expand * as a file wildcard.
grep 'roo*' /etc/passwd
The output will likely show multiple lines:
root:x:0:0:root:/root:/bin/bash
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
systemd-timesync:x:104:110:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
rtkit:x:108:113:RealtimeKit,,,:/proc:/usr/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
Let's analyze this result. The pattern 'roo*' searches for lines containing ro followed by zero or more o's.
- The
rootline matches because it containsroo(rofollowed by oneo). - The
proxyline matches because it containsro(rofollowed by zeroo's) in "proxy". - The
systemd-timesyncline matches because it containsroin "Synchronization". - The
rtkitline matches because it containsroin "proc". - The
operatorline matches because it containsroin both "operator" and "/root".
Now, let's look at the dot (.) metacharacter. The dot matches any single character. Execute the following command to see how its behavior differs:
grep 'ro.' /etc/passwd
This time, the output shows several matches:
root:x:0:0:root:/root:/bin/bash
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
systemd-timesync:x:104:110:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
rtkit:x:108:113:RealtimeKit,,,:/proc:/usr/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
The pattern 'ro.' searches for lines containing ro followed by exactly one of any character.
- The
rootline matches becauserois followed byoin "root". - The
proxyline matches becauserois followed byxin "proxy". - The
systemd-timesyncline matches becauserois followed bynin "Synchronization". - The
rtkitline matches becauserois followed bycin "proc". - The
operatorline matches becauserois followed by another character in "operator" and "/root".
By comparing the outputs, you can clearly see the power of regular expressions. Both patterns 'roo*' and 'ro.' match multiple lines, demonstrating how different metacharacters allow you to fine-tune your searches in different ways.
Use Extended Regular Expressions for Complex Searches
In this step, you will learn to use Extended Regular Expressions (ERE) to perform even more complex and powerful searches. ERE offers a richer set of metacharacters than Basic Regular Expressions (BRE). To enable ERE, you can use the grep -E command or its traditional alias, egrep. Using grep -E is the more modern and recommended approach.
First, let's explore quantifiers. In ERE, you can specify the exact number of times a character should appear using curly braces {}. For example, to find any line that has exactly two lowercase 'o's together, you can use the pattern o{2}.
Execute the following command. We enclose the pattern in single quotes to prevent the shell from misinterpreting the special characters.
grep -E 'o{2}' /etc/passwd
The output will show multiple lines containing "oo":
root:x:0:0:root:/root:/bin/bash
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
This command works because the pattern o{2} specifically matches two consecutive 'o' characters, found in "root", "spool", and other entries.
Next, let's look at alternation. This powerful ERE feature allows you to search for one of several possible patterns using the pipe symbol |, which acts as an 'OR' operator.
For instance, if you wanted to find a user record for either root or Root (in case you were unsure of the capitalization), you could use the following command:
grep -E 'root|Root' /etc/passwd
This command searches for any line containing either the string root or the string Root. The output shows:
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
Both the root user line and the operator line match because they both contain the lowercase "root" string.
Extended Regular Expressions, enabled with grep -E, provide a more expressive and powerful syntax for crafting complex search patterns, making grep an indispensable tool for text processing.
Summary
In this lab, you learned how to use the grep command to perform fundamental text searches in Linux. You started by executing basic searches for a specific string within a single file and then extended this to search across multiple files, observing how grep prefixes matching lines with their corresponding filenames. You also learned to use the -n option to display the line number for each match, which is useful for locating patterns within files.
Furthermore, you explored more advanced pattern matching capabilities by using anchors to find text at the beginning (^) or end ($) of a line. The lab progressed to cover the use of both basic and extended regular expressions, enabling you to construct more complex and powerful search patterns to find specific information within files.



