Open Source

10 ways to use grep to search files in Linux

The grep command is a powerful tool for searching for files or information. Learn some strategies for using it effectively.

ss2.jpg
Image: Scott Matteson/TechRepublic

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 prep). 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.lowell.litle.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.lowell.litle.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.lowell.litle.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.lowell.litle.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.lowell.litle.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.lowell.litle.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

About Scott Matteson

Scott Matteson is a senior systems administrator and freelance technical writer who also performs consulting work for small organizations. He resides in the Greater Boston area with his wife and three children.

Editor's Picks