$ grep root /etc/passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin $ grep -n root /etc/passwd 1:root:x:0:0:root:/root:/bin/bash 12:operator:x:11:0:operator:/root:/sbin/nologin -n, --line-number Prefix each line of output with the line number within its input file. $ 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:/etc/news v, --invert-match Invert the sense of matching, to select non-matching lines. $ grep -c bash /etc/passwd 2 $ grep -c nologin /etc/passwd 29 -c, --count Suppress normal output; instead print a count of matching lines for each input file. With the -v, --invert-match option (see below), count non-matching lines. $ grep -i ps ~/.bash* Binary file /home/trinity/.bashbashscript.swp matches /home/trinity/.bash_history:pstree -p /home/trinity/.bash_history:pstree $ grep -i ps ~/.bash* | grep -v history Binary file /home/shibu/.bashbashscript.swp matches -i, --ignore-case Ignore case distinctions in both the PATTERN and the input files. We now exclusively want to display lines starting with the string "root": $ grep -rwl 'ar' /home/trinity/ /home/trinity/.gnome-desktop/starthere.desktop /home/trinity/test -R, -r, --recursive Read all files under each directory, recursively; this is equiv- alent to the -d recurse option. -w, --word-regexp Select only those lines containing matches that form whole words. -x, --line-regexp Select only those matches that exactly match the whole line. -l, --files-with-matches Suppress normal output; instead print the name of each input file from which output would normally have been printed. The scanning will stop on the first match. $ grep ^root /etc/passwd root:x:0:0:root:/root:/bin/bash The caret ^ and the dollar sign $ are metacharacters that respectively match the empty string at the beginning and end of a line. The symbols \< and \> respectively match the empty string at the beginning and end of a word. The symbol \b matches the empty string at the edge of a word, and \B matches the empty string provided it’s not at the edge of a word. $ grep :$ /etc/passwd news:x:9:13:news:/etc/news: $ grep -w / /etc/fstab LABEL=/ / ext3 defaults 1 1 $ grep / /etc/fstab LABEL=/ / ext3 defaults 1 1 LABEL=/boot /boot ext3 defaults 1 2 none /dev/pts devpts gid=5,mode=620 0 0 none /proc proc defaults 0 0 none /dev/shm tmpfs defaults 0 0 /dev/hda4 swap swap defaults 0 0 /dev/fd0 /mnt/floppy auto noauto,owner,kudzu 0 0 /dev/cdrom /mnt/cdrom udf,iso9660 noauto,owner,kudzu,ro 0 0 Here is an example shell command that invokes GNU `grep': grep -i 'hello.*world' menu.h main.c
This lists all lines in the files `menu.h' and `main.c' that contain the string `hello' followed by the string `world'; this is because `.*' matches zero or more characters within a line. *Note Regular Expressions::. The `-i' option causes `grep' to ignore case, causing it to match the line `Hello, world!', which it would not otherwise match. *Note Invoking::, for more details about how to invoke `grep'.
Here are some common questions and answers about `grep' usage. 1. How can I list just the names of matching files? grep -l 'main' *.c lists the names of all C files in the current directory whose contents mention `main'. 2. How do I search directories recursively? grep -r 'hello' /home/gigi searches for `hello' in all files under the directory `/home/gigi'. For more control of which files are searched, use `find', `grep' and `xargs'. For example, the following command searches only C files: find /home/gigi -name '*.c' -print | xargs grep 'hello' /dev/null This differs from the command: grep -r 'hello' *.c
lists the names of all C files in the current directory whose
contents mention `main'. 2. How do I search directories recursively? grep -r 'hello' /home/gigi searches for `hello' in all files under the directory `/home/gigi'. For more control of which files are searched, use `find', `grep' and `xargs'. For example, the following command searches only C files: find /home/gigi -name '*.c' -print | xargs grep 'hello' /dev/null This differs from the command: grep -r 'hello' *.c which merely looks for `hello' in all files in the current directory whose names end in `.c'. Here the `-r' is probably unnecessary, as recursion occurs only in the unlikely event that one of `.c' files is a directory. 3. What if a pattern has a leading `-'? grep -e -cut here- * searches for all lines matching `--cut here--'. Without `-e', `grep' would attempt to parse `--cut here--' as a list of options. 4. Suppose I want to search for a whole word, not a part of a word? grep -w 'hello' * searches only for instances of `hello' that are entire words; it does not match `Othello'. For more control, use `\<' and `\>' to match the start and end of words. For example: grep 'hello\>' * searches only for words ending in `hello', so it matches the word `Othello'. 5. How do I output context around the matching lines? grep -C 2 'hello' * prints two lines of context around each matching line. 6. How do I force grep to print the name of the file? Append `/dev/null': grep 'eli' /etc/passwd /dev/null gets you: /etc/passwd:eli:DNGUTF58.IMe.:98:11:Eli Smith:/home/do/eli:/bin/bash 7. Why do people use strange regular expressions on `ps' output? ps -ef | grep '[c]ron' If the pattern had been written without the square brackets, it would have matched not only the `ps' output line for `cron', but also the `ps' output line for `grep'. Note that some platforms `ps' limit the ouput to the width of the screen, grep does not have any limit on the length of a line except the available memory.
8. Why does `grep' report "Binary file matches"?
If `grep' listed all matching "lines" from a binary file, it would probably generate output that is not useful, and it might even muck up your display. So GNU `grep' suppresses output from files that appear to be binary files. To force GNU `grep' to output lines even from files that appear to be binary, use the `-a' or `--binary-files=text' option. To eliminate the "Binary file matches" messages, use the `-I' or `--binary-files=without-match' option. 9. Why doesn't `grep -lv' print nonmatching file names? `grep -lv' lists the names of all files containing one or more lines that do not match. To list the names of all files that contain no matching lines, use the `-L' or `--files-without-match' option. 10. I can do OR with `|', but what about AND? grep 'paul' /etc/motd | grep 'franc,ois' finds all lines that contain both `paul' and `franc,ois'. 11. How can I search in both standard input and in files? Use the special file name `-':
cat /etc/passwd | grep 'alain' - /etc/motd
12. How to express palindromes in a regular expression? It can be done by using the back referecences, for example a palindrome of 4 chararcters can be written in BRE. grep -w -e '\(.\)\(.\).\2\1' file It matches the word "radar" or "civic". Guglielmo Bondioni proposed a single RE that finds all the palindromes up to 19 characters long. egrep -e '^(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?).?\9\8\7\6\5\4\3\2\1$' file Note this is done by using GNU ERE extensions, it might not be portable on other greps.