For example, suppose we have a text file called
applist.txt and we want to find out what lines of it contain the word “desktop”. It’s easy with pipes. We list the contents of the file
applist.txt and send the results to
grep, which then filters all lines containing the desired word “desktop”, and displays those lines on your screen:
$ cat applist.txt | grep desktop
grep is, like many Linux commands, case sensitive. This means that the above matches only “desktop”, not “Desktop” or “DESKTOP”. With the
-i option the search is case insensitive:
$ cat applist.txt | grep -i desktop
What if you’d like to scroll the output of
grep? Well, because
grep sends its results to standard output, you can just pipe them to
$ cat applist.txt | grep -i desktop | less
Of course you can redirect the output of
grep to a file, if you want:
$ cat applist.txt | grep -i desktop > desktop.txt
4.2.1. What is grep?
grep searches the input files for lines containing a match to a given pattern list. When it finds a match in a line, it copies the line to standard output (by default), or whatever other sort of output you have requested with options.
Though grep expects to do the matching on text, it has no limits on input line length other than available memory, and it can match arbitrary characters within a line. If the final byte of an input file is not a newline, grep silently supplies one. Since newline is also a separator for the list of patterns, there is no way to match newline characters in a text.
cathy ~> grep root /etc/passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin cathy ~> grep -n root /etc/passwd 1:root:x:0:0:root:/root:/bin/bash 12:operator:x:11:0:operator:/root:/sbin/nologin cathy ~> grep -v bash /etc/passwd | grep -v nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt news:x:9:13:news:/var/spool/news: mailnull:x:47:47::/var/spool/mqueue:/dev/null xfs:x:43:43:X Font Server:/etc/X11/fs:/bin/false rpc:x:32:32:Portmapper RPC user:/:/bin/false nscd:x:28:28:NSCD Daemon:/:/bin/false named:x:25:25:Named:/var/named:/bin/false squid:x:23:23::/var/spool/squid:/dev/null ldap:x:55:55:LDAP User:/var/lib/ldap:/bin/false apache:x:48:48:Apache:/var/www:/bin/false cathy ~> grep -c false /etc/passwd 7 cathy ~> grep -i ps ~/.bash* | grep -v history /home/cathy/.bashrc:PS1="\[33[1;44m\]$USER is in \w\[33[0m\] "
With the first command, user cathy displays the lines from /etc/passwd containing the string root.
Then she displays the line numbers containing this search string.
With the third command she checks which users are not using bash, but accounts with the nologin shell are not displayed.
Then she counts the number of accounts that have /bin/false as the shell.
The last command displays the lines from all the files in her home directory starting with ~/.bash, excluding matches containing the string history, so as to exclude matches from ~/.bash_history which might contain the same string, in upper or lower cases. Note that the search is for the string “ps”, and not for the command ps.
Now let’s see what else we can do with grep, using regular expressions.
|If you are not on Linux|
|We use GNU grep in these examples, which supports extended regular expressions. GNU grep is the default on Linux systems. If you are working on proprietary systems, check with the -V option which version you are using. GNU grep can be downloaded from http://gnu.org/directory/.|
From the previous example, we now exclusively want to display lines starting with the string “root”:
cathy ~> grep ^root /etc/passwd root:x:0:0:root:/root:/bin/bash
If we want to see which accounts have no shell assigned whatsoever, we search for lines ending in “:”:
cathy ~> grep :$ /etc/passwd news:x:9:13:news:/var/spool/news:
To check that PATH is exported in ~/.bashrc, first select “export” lines and then search for lines starting with the string “PATH”, so as not to display MANPATH and other possible paths:
cathy ~> grep export ~/.bashrc | grep '\<PATH' export PATH="/bin:/usr/lib/mh:/lib:/usr/bin:/usr/local/bin:/usr/ucb:/usr/dbin:$PATH"
Similarly, \> matches the end of a word.
If you want to find a string that is a separate word (enclosed by spaces), it is better use the -w, as in this example where we are displaying information for the root partition:
cathy ~> grep -w / /etc/fstab LABEL=/ / ext3 defaults 1 1
If this option is not used, all the lines from the file system table will be displayed.
A bracket expression is a list of characters enclosed by “[” and “]”. It matches any single character in that list; if the first character of the list is the caret, “^”, then it matches any character NOT in the list. For example, the regular expression “” matches any single digit.
Within a bracket expression, a range expression consists of two characters separated by a hyphen. It matches any single character that sorts between the two characters, inclusive, using the locale’s collating sequence and character set. For example, in the default C locale, “[a-d]” is equivalent to “[abcd]”. Many locales sort characters in dictionary order, and in these locales “[a-d]” is typically not equivalent to “[abcd]”; it might be equivalent to “[aBbCcDd]”, for example. To obtain the traditional interpretation of bracket expressions, you can use the C locale by setting the LC_ALL environment variable to the value “C”.
Finally, certain named classes of characters are predefined within bracket expressions. See the grep man or info pages for more information about these predefined expressions.
cathy ~> grep [yf] /etc/group sys:x:3:root,bin,adm tty:x:5: mail:x:12:mail,postfix ftp:x:50: nobody:x:99: floppy:x:19: xfs:x:43: nfsnobody:x:65534: postfix:x:89:
In the example, all the lines containing either a “y” or “f” character are displayed.
Use the “.” for a single character match. If you want to get a list of all five-character English dictionary words starting with “c” and ending in “h” (handy for solving crosswords):
cathy ~> grep '\<c...h\>' /usr/share/dict/words catch clash cloth coach couch cough crash crush
If you want to display lines containing the literal dot character, use the -F option to grep.
For matching multiple characters, use the asterisk. This example selects all words starting with “c” and ending in “h” from the system’s dictionary:
cathy ~> grep '\<c.*h\>' /usr/share/dict/words caliph cash catch cheesecloth cheetah --output omitted--
If you want to find the literal asterisk character in a file or output, use single quotes. Cathy in the example below first tries finding the asterisk character in /etc/profile without using quotes, which does not return any lines. Using quotes, output is generated:
cathy ~> grep * /etc/profile cathy ~> grep '*' /etc/profile for i in /etc/profile.d/*.sh ; do