The grep is one of the powerful commands used in Linux for searching and matching text patterns within one or more files. The word grep stands for "Global Regular Expression Print". It uses the capabilities of regular expressions to search and match. The grep command is primarily used to locate specific patterns and display lines matching them.
Syntax of grep
The basic syntax of grep command is as follows:
grep [options] pattern [file(s)]
Where,
pattern : The regular expression you want to search for.
[files(s)] : One more file to search for regular expressions.
Grep Options
The following table lists useful options with the grep command.
Options
Description
-n
Display matching lines along with the line number.
-w
Match with the exact word.
-i
Tell grep to ignore case.
-E
Tell grep to add support for the extended regular expression.
-r or -R
Recursive search. The capital R does the same but follows the symlinks.
-q
Suppress the output.
-v
Display non-matching lines.
-l
Print only the matching file names.
-e
Match multiple patterns.
-f
Search patterns from a file.
-b
Display byte offset of the match.
-c
Display the count of matching lines.
-o
Display only the matching parts of a line.
-b
Tell grep to treat the binary file as a normal text file.
-A, -B, and -C
Context-based searching - after, before, and context respectively.
Basic Text Searching
Let's look into the basic text searching using the grep command. By default, grep print lines contain the matching pattern.
Searching in a single file
To search for a pattern in a single file, use the following command:
grep pattern filename
Example:
grep Linux samplfile.txt
This command search for the literal string Linux and print all lines that match it. Remember grep is by default case sensitive.
If you see -n option, then the output will show each matching line along with its line number.
grep -n Linux samplfile.txt
Note: For literal string placing single quotes and no quotes tell grep no difference. For searching patterns with spaces, special characters, or when combing with regex you can use double quotes.
In the output, you can see the grep matched the word "Linux" appears as part of Linux and "Linux"Opsys. Instead, you can perform an exact word match using -w option.
Example:
grep -w Linux samplfile.txt
This grep command searches for the exact word "Linux" in samplfile.txt file and matches the lines it matches. You can see from the output the word "LinuxOpsys" is not highlighted.
Displaying Matched Lines from Multiple Files
You can pass multiple files to grep as arguments to search patterns. This is will search the specified pattern in all files and display lines containing the matches.
Example:
grep Linux samplfile.txt samplefile2.txt samplefile3.txt
This command matches the word "Linux" from multiples files and display the lines containing it along with the filenames.
Case Sensitivity
As mentioned before grep by default perform exact match for the specified pattern. Mean it can distinguish between uppercase and lowercase.
Lets look into the default action:
grep Linux samplfile.txt
The output contain lines containing the word "Linux" and not "linux" or "LINux" etc.
To tell grep to search by ignoring the case use -i or --ignore-case option.
Example:
grep -i Linux samplfile.txt
This command performed a case-insensitive search and from the output you can see grep print lines containing both "Linux" and "linux".
Extended Regular Expressions
The grep command supports basic regular expressions (BRE) , Perl-Compatible Regular Expressions (PCRE), and extended regular expressions. By default, grep uses BRE. for pattern matching.
The Extended regular expression (ERE) supports more metacharacters and features. To tell grep to use ERE pattern (support meta characters such as ( ) { } ? + and |) use -E (or 'egrep') option.
Example:
grep -E 'Linux|linux' samplfile.txt
This command tells grep command use extended regular expressions to search lines containing either "Linux" or "linux" in the file named samplfile.txt.
Instead of using grep -E, you can use egrep command for ERE pattern search.
Example:
egrep 'Linux|linux|awesome' samplefile.txt
This command searches for lines containing either "Linux," "linux," or "awesome" in the file samplefile.txt. On a side note, the egrep deprecated recommends using grep -E command.
Note when we using without -E some characters like like +, ?, |, () have to be escaped by backslashes to have special meaning.
Both commands perform the same ie match lines in the file specified by samplefile.txt that start with one or more digits.
Recursive Searching
To tell grep to perform recursive search use -r option. This enables it to locate the pattern in all files within the specified directory and its subdirectories recursively. You may also use -R option, the only difference is that it follows symbolic links.
Example:
grep -r Linux dir1
This command recursive searches the pattern "Linux" in all files under the dir1 directory.
You can replace dir1 with . (dot) to tell grep to start searching from the current directory.
Some useful option that comes in handy when grep recursive are --include, --exclude , --exclude-dir and -l options.
Where,
--include: Allows to limit the search to specific a pattern or file extension. Example: grep -r --include='*.txt' 'pattern' directory
--exclude: Allow specific patterns or file extensions to exclude from the search.
--exclude-dir: Allows specify the directory you want to exclude from the search.
-l: To print names of files that contain the pattern.
Controlling Output
Lets look into some useful options to control the grep results.
Displaying Line Numbers
The -n option tells grep to print line numbers where the search pattern is found, followed by a colon and the actual text of the line.
grep -n Linux **/*.txt
This command searches the string "Linux" recursively (-R option not needed as globstar ** takes care of it) in all .txt files in the current directory and its subdirectories with line numbers at the beginning.
Displaying Only File Names
By default, grep prints the lines which contain the match. Instead, if you want to print only the filenames that contain the pattern use the -l (lowercase L) option.
grep -Rl Linux dir1
This command searches the pattern "Linux" recursive on dir1 directory and prints filenames where it finds the match.
Suppressing Normal Output
Use -q or --quiet or --silent option to tell grep command to suppress the output. Even if it has matched many lines grep does not output them.
Example:
grep -q Linux samplefile.txt
From the output you can see the grep silently exit with no output.
This comes useful in script where we care only about the exit status - if match found the exit with status 0 otherwise non-zero value.
Invert the match
Use -v option with grep to invert the match. This means it will match all lines that do NOT contain the pattern specified.
Example:
grep -v Linux samplfile.txt
Here all the lines containing "Linux" is ignored. In the output you are seeing a line with "linux", this is because grep is default case sensitive, you can ignore the case using -i.
Let's take another useful example where you need to read only the only the active configuration lines in nginx.
grep -v '^\s*$\|^\s*\#' /etc/nginx/nginx.conf
This command displays the content of the /etc/nginx/nginx.conf file while excluding empty lines and lines starting with comments (commented-out lines).
Searching Multiple Patterns
The -e option in grep is commonly used to specify multiple patterns for grep to match.
This command used -e option to match two patterns "Linux" and "Operating system" in the samplefile.txt. In the second pattern we have used double quotes because it has a space.
Read pattern from a file
Use -f option in grep to read patterns from a file. Each line in the file should contain a separate pattern to match.
Example:
grep -f mypatterns.txt samplfile.txt
Here mypatterns.txt file contains a list of the following patterns to search:
$ cat mypatterns.txt
Linux
Operating
linux
The grep command matches all patterns listed in the file.
Display byte Offset of match
You can use -b option with grep to print byte offset of each match at the beginning of the line followed by a colon.
Example:
grep -b Linux samplfile.txt
This command print display byte offset at the beginning of each line where the pattern Linux matches. The byte offset is the number of bytes from the start of the file to the start of the line.
Counting Matches
Use -c option with grep to count the matching number of lines. Remember this won't count all the matches.
Example:
grep -c Linux samplefile.txt
Output 5 indicates there is a total of 5 matching lines where the string "Linux" matches. Whereas the total count of strings in the entire file is 8.
To tell grep to get the count of all occurrences of the pattern we can combine -o and wc -l command.
Example:
grep -o Linux samplefile.txt | wc -l
Where,
-o or --only-matching : This option to print only the matched parts of a line.
wc -l : count the number of lines in the input and display the result.
The command shows the word "Linux" appears 8 times in the samplefile.txt file.
Working with Binary Files
By default, grep search pattern assumes it contains a human-readable text file. When it encounters a binary file it won't be able to process it. But you can pass -a or --text option to tell grep to treat a binary file as a normal text file.
Example:
grep -a driverlicence /dev/sda
This command search for the pattern "driverlicense" in the binary file /dev/sda.
Combining grep with Other Tools
The grep command can be combined with other Linux commands to become even more versatile and useful. Mostly commonly grep is combined with find, awk, cut, uniq, sort, and cat commands. Let's look into a couple of examples.
Combine with cat:
cat samplefile.txt | grep "Linux"
This command search for the string "Linux" in the content of the samplefile.txt. Instead, you can achieve the same result by directly using grep.
This command search for the string "Linux" in all the files with a .txt extension in the current directory and its subdirectories. It displays the filename before each matching line which makes it easier to identify which file contains the match.
Context-based Searching
In grep, context-based searching allows displaying lines of text that match the pattern along with surrounding lines. The context-supporting option with grep is -A, -B, and -C.
Where,
-A : Display matching lines with specified lines after that.
-B : Display matching lines with specified lines before that.
-C : Display matching lines with specified lines before and after that.
Examples of -A, -B, and -C options.
The following command matches the string "two" and displays the matches with 2 lines after that.
grep -A 2 two contextfile.txt
To match the string "five" and displays the matches with 2 lines before that.
grep -B 2 five contextfile.txt
Here this command matches the string "three" and displays the matches with 2 lines before and after that.
grep -C 2 three contextfile.txt
If this resource helped you, let us know your care by a Thanks Tweet.
Did you find this article helpful?
We are glad you liked the article. Share with your friends.
Comments