Windows search is not without certain charms, but when I need to find files or their contents, or search for specific system information, the grep command in Linux never ceases to amaze me through its power and versatility.
There are multiple versions of grep; plain regular grep, egrep (extended grep) and fgrep (fixed grep). The latter two have different methods for working with characters and search strings. I’ll focus on regular grep for the purpose of this article, which is intended as a beginning tutorial for this handy and reliable command.
The syntax of grep is as follows:
grep [options] pattern [files]
The options and patterns you can use with grep are varied and diverse. Here are 10 examples to help sharpen your skills.
1.Search a file for a specific word
This is really one of the most elementary uses for grep. Let’s say I want to inspect the contents of the /var/log/secure log for any instances of a failure. I would type:
grep failure /var/log/secure
This is an example of what grep might then return:
Apr 4 06:45:29 smatteso-vm1 sshd[14836]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost= qualys-corp.testdomain.com user=8boa5lv2rn8pso8
Apr 4 06:45:31 smatteso-vm1 sshd[14844]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost= qualys-corp.testdomain.com user=13hr26mnm8wo4k
Add the -i switch (e.g. grep -i) to conduct a case insensitive search. In the example above this would return the lowercase “failure,” uppercase “FAILURE” or any combination thereof, such as “Failure.”.
2.Search a file for multiple words
This command permits you to check for multiple words in a file – note the use of the single quotes, the backslash and the pipe command between them:
grep ‘opened\|closed’ /var/log/secure
This is what grep might return:
Apr 2 03:45:07 smatteso-vm1 sshd[16278]: Connection closed by 10.1.7.101
Apr 2 03:46:42 smatteso-vm1 su: pam_unix(su-l:session): session opened for user phxinst1 by (uid=0)
Apr 2 03:46:45 smatteso-vm1 su: pam_unix(su-l:session): session closed for user phxinst1
Apr 2 03:46:45 smatteso-vm1 su: pam_unix(su-l:session): session opened for user phxinst1 by (uid=0)
3.Get an instance count
You may not want to actually see the output of the grep command but have it tell you how many matches your search found. This is performed using the -c (count) switch:
grep failure /var/log/secure -c
Grep will return a number like this:
12
You can do some clever things with this switch. For instance, if I want to know how many processors are in my system I could type:
grep -c processor /proc/cpuinfo
4.Display the line numbers of each match
It can be helpful to know which line number your search results appear on. To do so, add the -n (number) switch:
grep -n failure /var/log/secure
Grep would then return something like this:
1601:Apr 4 06:45:29 smatteso-vm1 sshd[14836]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost= qualys-corp.testdomain.com user=8boa5lv2rn8pso8
1612:Apr 4 06:45:31 smatteso-vm1 sshd[14844]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost= qualys-corp.testdomain.com user=13hr26mnm8wo4k
5.Return only a specific number of matches
Let’s say I want to only see the first five search results. I can narrow these down using the -m (maximum count) switch:
grep -m5 failure /var/log/secure
Here’s an example of the results:
Apr 4 06:45:29 smatteso-vm1 sshd[14836]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost= qualys-corp.testdomain.com user=8boa5lv2rn8pso8
Apr 4 06:45:31 smatteso-vm1 sshd[14844]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost= qualys-corp.testdomain.com
user=13hr26mnm8wo4k
Note there cannot be a space between “-m” and your maximum count value.
6.Display all entries which are NOT a match.
There are some scenarios in which you might want to do a reverse search and show results which do NOT match your input. Just add the -v switch here. For instance, to see entries in the /var/log/secure file which do not represent the word “failure” type:
grep -v failure /var/log/secure
And then you would get results like this:
Apr 2 03:45:07 smatteso-vm1 sshd[16278]: Connection closed by 10.1.7.101
Apr 2 03:46:42 smatteso-vm1 su: pam_unix(su-l:session): session opened for user phxinst1 by (uid=0)
Apr 2 03:46:45 smatteso-vm1 su: pam_unix(su-l:session): session closed for user phxinst1
Apr 2 03:46:45 smatteso-vm1 su: pam_unix(su-l:session): session opened for user phxinst1 by (uid=0)
Of course you can combine strings such as -v and -n:
grep -v -n failure /var/log/secure
Which would show you all the non-matching entries with their associated line numbers:
1:Apr 2 03:45:07 smatteso-vm1 sshd[16278]: Connection closed by 10.1.7.101
2:Apr 2 03:46:42 smatteso-vm1 su: pam_unix(su-l:session): session opened for user phxinst1 by (uid=0)
3:Apr 2 03:46:45 smatteso-vm1 su: pam_unix(su-l:session): session closed for user phxinst1
4:Apr 2 03:46:45 smatteso-vm1 su: pam_unix(su-l:session): session opened for user phxinst1 by (uid=0)
5:Apr 2 03:46:48 smatteso-vm1 su: pam_unix(su-l:session): session closed for user phxinst1
7.Search across multiple files
Grep can do much more than just search the contents of a specific file. You can use what’s known as a recursive search to cover entire directories, subdirectories, or the entire file system and get results showing each filename that contains your search value.
This is performed using the -r switch, which I’ll use to search for my user account name in the /etc directory:
grep -r “smatteso” /etc
Here’s an example of the results:
/etc/hosts:10.1.52.237 smatteso-vm1.dwi.testdomain.com smatteso-vm1
/etc/sysconfig/network-scripts/ifcfg-eth0:HOSTNAME=”smatteso-vm1″
/etc/sysconfig/rhn/systemid:<value><string>smatteso-vm1.dwi.testdomain.com</string></value>
/etc/sysconfig/network:HOSTNAME=smatteso-vm1
You can search the entire file system by changing that “/etc” to “/”:
grep -r “smatteso” /
(note this can be quite a time-consuming operation!)
8.Display only the filenames which match the search
I’m not a fan of clutter, so to get just the list of filenames which match my search (and not the contents of the files themselves) I can add the -l switch:
grep -rl “smatteso” /etc
Which would return results like this:
/etc/hosts
/etc/sysconfig/network-scripts/ifcfg-eth0
/etc/sysconfig/rhn/systemid
/etc/sysconfig/network
Just as discussed earlier, you can flip this to display the filenames which do not contain your search term(s), using the -L switch rather than -l:
grep -rL “smatteso” /etc
9.Search for messages logged by date
One especially helpful element when using grep is to comb through log files searching for messages which were logged on a certain date. Say I want to see everything logged on April 5th:
grep “Apr 5” /var/log/messages
I would get results like this:
Apr 5 00:00:01 smatteso-vm1 audispd: node=smatteso-vm1 type=USER_ACCT msg=audit(1491364801.741:135867): user pid=50149 uid=0 auid=4294967295 ses=4294967295 msg=’op=PAM:accounting acct=”phxinst1″ exe=”/usr
/sbin/crond” hostname=? addr=? terminal=cron res=success’
Apr 5 00:00:01 smatteso-vm1 audispd: node=smatteso-vm1 type=USER_ACCT msg=audit(1491364801.741:135866): user pid=50143 uid=0 auid=4294967295 ses=4294967295
This works for a specific timeframe too if you add that in, of course. To see only the messages logged at 6 a.m. I can add “06:00” to the command:
grep “Apr 5 06:00” /var/log/messages
Apr 5 06:00:01 smatteso-vm1 audispd: node=smatteso-vm1 type=USER_ACCT msg=audit(1491386401.774:143444): user pid=33946 uid=0 auid=4294967295 ses=4294967295 msg=’op=PAM:accounting acct=”phxinst1″ exe=”/usr/sbin/crond” hostname=? addr=? terminal=cron res=success’
Apr 5 06:00:01 smatteso-vm1 audispd: node=smatteso-vm1 type=USER_ACCT msg=audit(1491386401.774:143445): user pid=33945 uid=0 auid=4294967295 ses=4294967295 msg=’op=PAM:accounting acct=”phxinst1″ exe=”/usr/sbin/crond” hostname=? addr=? terminal=cron res=success’
10.Use grep with other commands
Grep can be used with any other command you like. Let’s say I want to find any log files containing the word spice. I can use the find command and pipe the results to grep as follows:
find . -name “*.log” | grep -i spice
Here’s an example of the results:
./spice-vdagent.log
The history file, which contains a list of recently-typed commands, is one of the best elements of Linux. It’s also possible to grep the history file for specific terms (for example, “pam_tally2”) to see when they were last used and what the appropriate syntax is:
history | grep pam_tally2
324 2017-04-06 13:50:25 pam_tally2
325 2017-04-06 13:50:29 pam_tally2 -u smatteso -r
350 2017-04-06 14:05:44 history | grep pam_tally2
You can use grep with “netstat” to look at listening ports, say port 22 for instance:
netstat -anp | grep 22
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 2154/sshd
tcp 0 0 10.1.52.237:22 10.1.13.63:51704 ESTABLISHED 40441/sshd
tcp 0 32 10.1.52.237:22 10.1.13.63:51701 ESTABLISHED 40434/sshd
tcp 0 0 :::22 :::* LISTEN 2154/sshd
You can also look for a specific process identifier. In this example I’ll check to see if any processes called “spice” are running:
ps -aux | grep spice
root 2179 0.0 0.0 15900 1076 ? Ss Mar31 0:00 /usr/sbin/spice-vdagentd
root 2855 0.0 0.0 103328 888 pts/0 S+ 12:41 0:00 grep spice
gdm 5430 0.0 0.0 34488 1604 ? Ss Mar31 0:00 /usr/bin/spice-vdagent
This is just the basic tip of the iceberg representing the capabilities of grep. In a follow-up article I’ll discuss some more advanced methods for using the command to get even more helpful and granular results.
To learn more about grep, use the command “man grep” or “grep –help.” You can also download a version of grep for Windows.
Also see
- How to free disk space on Linux systems
- How to resize a virtual Red Hat Enterprise Linux partition
- How to add version control for your Linux /etc directory
- How to use a ramdisk on Linux