What is grep?
grep is a unix command used to find a text(or pattern) in a file(s) or stream output. By default grep displays matching lines.Syntax of grep command is
grep options pattern filename(s)
Open terminal and execute following command from home directory(e.g. /home/dev001 )
grep PATH .profile
Sample Output
# set PATH so it includes user's private bin if it exists
PATH="$HOME/bin:$PATH"
Explanation:
In .profile file above two lines contain the PATH string. Hence two lines displayed in terminal as output.
Same output can be achieved by using following command
cat .profile | grep PATH
cat simply displays content of .profile in terminal(stream output) and grep command finds PATH string from that content.
For reference, sample .profile is also provided here
1 # ~/.profile: executed by the command interpreter for login shells.
2 # This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
3 # exists.
4 # see /usr/share/doc/bash/examples/startup-files for examples.
5 # the files are located in the bash-doc package.
6
7 # the default umask is set in /etc/profile; for setting the umask
8 # for ssh logins, install and configure the libpam-umask package.
9 #umask 022
10
11 # if running bash
12 if [ -n "$BASH_VERSION" ]; then
13 # include .bashrc if it exists
14 if [ -f "$HOME/.bashrc" ]; then
15 . "$HOME/.bashrc"
16 fi
17 fi
18
19 # set PATH so it includes user's private bin if it exists
20 if [ -d "$HOME/bin" ] ; then
21 PATH="$HOME/bin:$PATH"
22 fi
Can I search a text in multiple files or in a directory using grep?
We can search in multiple files by specifying file names. For searching in a directory use recursive option ( -r or -R ) and specify directory name
Say we are searching for INFO statement in LOGFILES directory which has three log files i.e Logfile1, Logfile2 and LogFile3
sample input command :
grep "INFO" Logfile1 Logfile2 LogFile3
grep -r "INFO" LOGFILES
Looks good but grep command seems not working when I search for a string that contains whitespace. Say for example unmask 022(content of line 9).
Input command :
grep umask 022 .profile
Output:
grep: 022: No such file or directory
.profile:# the default umask is set in /etc/profile; for setting the umask
.profile:# for ssh logins, install and configure the libpam-umask package.
.profile:#umask 022
Explanation:
grep takes first parameter as input search string(pattern) and rest of the parameters are considered as input files for searching. So in this case unmask string is searched in 022 and .profile files. As there is no file exists named 022 in home folder, first line comes as output. Rest of the result showing presence of unmask string in .profile file.
Solution :
Put double quotes in search input string.
grep "umask 022" .profile
Output:
#umask 022
Origin of grep :
grep comes from the ed command g/re/p (globally search a regular expression and print)and it works same as grep.ie. doing a global search with the regular expression and printing all matching lines. Both ed editor and grep command created by Ken ThompsonLet's start
Open terminal and execute following command from home directory(e.g. /home/dev001 )
grep PATH .profile
Sample Output
# set PATH so it includes user's private bin if it exists
PATH="$HOME/bin:$PATH"
Explanation:
In .profile file above two lines contain the PATH string. Hence two lines displayed in terminal as output.
Same output can be achieved by using following command
cat .profile | grep PATH
cat simply displays content of .profile in terminal(stream output) and grep command finds PATH string from that content.
For reference, sample .profile is also provided here
1 # ~/.profile: executed by the command interpreter for login shells.
2 # This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
3 # exists.
4 # see /usr/share/doc/bash/examples/startup-files for examples.
5 # the files are located in the bash-doc package.
6
7 # the default umask is set in /etc/profile; for setting the umask
8 # for ssh logins, install and configure the libpam-umask package.
9 #umask 022
10
11 # if running bash
12 if [ -n "$BASH_VERSION" ]; then
13 # include .bashrc if it exists
14 if [ -f "$HOME/.bashrc" ]; then
15 . "$HOME/.bashrc"
16 fi
17 fi
18
19 # set PATH so it includes user's private bin if it exists
20 if [ -d "$HOME/bin" ] ; then
21 PATH="$HOME/bin:$PATH"
22 fi
Can I search a text in multiple files or in a directory using grep?
We can search in multiple files by specifying file names. For searching in a directory use recursive option ( -r or -R ) and specify directory name
Say we are searching for INFO statement in LOGFILES directory which has three log files i.e Logfile1, Logfile2 and LogFile3
sample input command :
grep "INFO" Logfile1 Logfile2 LogFile3
grep -r "INFO" LOGFILES
Looks good but grep command seems not working when I search for a string that contains whitespace. Say for example unmask 022(content of line 9).
Input command :
grep umask 022 .profile
Output:
grep: 022: No such file or directory
.profile:# the default umask is set in /etc/profile; for setting the umask
.profile:# for ssh logins, install and configure the libpam-umask package.
.profile:#umask 022
Explanation:
grep takes first parameter as input search string(pattern) and rest of the parameters are considered as input files for searching. So in this case unmask string is searched in 022 and .profile files. As there is no file exists named 022 in home folder, first line comes as output. Rest of the result showing presence of unmask string in .profile file.
Solution :
Put double quotes in search input string.
grep "umask 022" .profile
Output:
#umask 022
Can I provide single quote instead of double quotes in pattern search string(i.e. 'umask 022' )?
single quote and double quotes in search string will act in same way if search string does not contain any special character(s).
For example grep "umask 022" .profile and
grep 'umask 022' .profile will produce identical result But say we are searching for $HOME string in .profile file.
grep "$HOME" .profile provide no result where as
grep '$HOME' .profile gives following output
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
if [ -d "$HOME/bin" ] ; then
PATH="$HOME/bin:$PATH"
WHY?
If we run grep "$HOME" .profile then first $HOME(e.g. /home/dev001 ) is evaluated. So the command becomes
grep "/home/dev001" .profile
"/home/dev001" text is not present in .profile so grep result is blank .
On the other hand '$HOME' does not evaluate value of $HOME. So we get above results.
Usage of single quote or Double quotes in search pattern basically depends on your requirement.
We can use "\$HOME" instead of "$HOME" as escape character "\" removes special meaning of "$".
It is not possible to provide exact string for searching every time. How can I use grep in that scenario?
Answer: You can use regular expression and also case insensitive search.
In next blog we will explore regular expression.
Example:
grep -i "bash" .profile
Output:
# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
# see /usr/share/doc/bash/examples/startup-files for examples.
# the files are located in the bash-doc package.
# if running bash
if [ -n "$BASH_VERSION" ]; then
# include .bashrc if it exists
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
I have huge log file and I am searching for "ERROR" occurence. Can I print line number in search result.
single quote and double quotes in search string will act in same way if search string does not contain any special character(s).
For example grep "umask 022" .profile and
grep 'umask 022' .profile will produce identical result But say we are searching for $HOME string in .profile file.
grep "$HOME" .profile provide no result where as
grep '$HOME' .profile gives following output
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
if [ -d "$HOME/bin" ] ; then
PATH="$HOME/bin:$PATH"
WHY?
If we run grep "$HOME" .profile then first $HOME(e.g. /home/dev001 ) is evaluated. So the command becomes
grep "/home/dev001" .profile
"/home/dev001" text is not present in .profile so grep result is blank .
On the other hand '$HOME' does not evaluate value of $HOME. So we get above results.
Usage of single quote or Double quotes in search pattern basically depends on your requirement.
We can use "\$HOME" instead of "$HOME" as escape character "\" removes special meaning of "$".
It is not possible to provide exact string for searching every time. How can I use grep in that scenario?
Answer: You can use regular expression and also case insensitive search.
In next blog we will explore regular expression.
Example:
grep -i "bash" .profile
Output:
# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
# see /usr/share/doc/bash/examples/startup-files for examples.
# the files are located in the bash-doc package.
# if running bash
if [ -n "$BASH_VERSION" ]; then
# include .bashrc if it exists
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
I have huge log file and I am searching for "ERROR" occurence. Can I print line number in search result.
Yes. use grep -n "ERROR" <logfilename(s)>
I want to find number of "ERROR" occurrence in my application log file.
use grep -c "ERROR" <logfilename(s)> to count search string occurrence in input file(s)
In .profile file I saw many comment lines started with #. Is it possible to search lines that does not have #?
use grep -v "#" .profile
Output:
if [ -n "$BASH_VERSION" ]; then
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi
if [ -d "$HOME/bin" ] ; then
PATH="$HOME/bin:$PATH"
fi
I want to find number of "ERROR" occurrence in my application log file.
use grep -c "ERROR" <logfilename(s)> to count search string occurrence in input file(s)
In .profile file I saw many comment lines started with #. Is it possible to search lines that does not have #?
use grep -v "#" .profile
Output:
if [ -n "$BASH_VERSION" ]; then
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi
if [ -d "$HOME/bin" ] ; then
PATH="$HOME/bin:$PATH"
fi