manpagez: man pages & more
info grep
Home | html | info | man

File: grep.info,  Node: Usage,  Next: Performance,  Prev: Regular Expressions,  Up: Top

4 Usage
*******

Here is an example 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.

   Here is a more complex example, showing the location and contents of
any line containing ‘f’ and ending in ‘.c’, within all files in the
current directory whose names start with non-‘.’, contain ‘g’, and end
in ‘.h’.  The ‘-n’ option outputs line numbers, the ‘--’ argument treats
any later arguments as file names not options even if ‘*g*.h’ expands to
a file name that starts with ‘-’, and the empty file ‘/dev/null’ causes
file names to be output even if only one file name happens to be of the
form ‘*g*.h’.

     grep -n -- 'f.*\.c$' *g*.h /dev/null

Note that the regular expression syntax used in the pattern differs from
the globbing syntax that the shell uses to match file names.

   *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' test-*.c

     lists names of ‘test-*.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 ‘/home/gigi’ directory.
     For more control over which files are searched, use ‘find’ and
     ‘grep’.  For example, the following command searches only C files:

          find /home/gigi -name '*.c' ! -type d \
            -exec grep -H 'hello' '{}' +

     This differs from the command:

          grep -H 'hello' /home/gigi/*.c

     which merely looks for ‘hello’ in non-hidden C files in
     ‘/home/gigi’ whose names end in ‘.c’.  The ‘find’ command line
     above is more similar to the command:

          grep -r --include='*.c' 'hello' /home/gigi

  3. What if a pattern or file has a leading ‘-’?  For example:

          grep "$pattern" *

     can behave unexpectedly if the value of ‘pattern’ begins with ‘-’,
     or if the ‘*’ expands to a file name with leading ‘-’.  To avoid
     the problem, you can use ‘-e’ for patterns and leading ‘./’ for
     files:

          grep -e "$pattern" ./*

     searches for all lines matching the pattern in all the working
     directory's files whose names do not begin with ‘.’.  Without the
     ‘-e’, ‘grep’ might treat the pattern as an option if it begins with
     ‘-’.  Without the ‘./’, there might be similar problems with file
     names beginning with ‘-’.

     Alternatively, you can use ‘--’ before the pattern and file names:

          grep -- "$pattern" *

     This also fixes the problem, except that if there is a file named
     ‘-’, ‘grep’ misinterprets the ‘-’ as standard input.

  4. Suppose I want to search for a whole word, not a part of a word?

          grep -w 'hello' test*.log

     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\>' test*.log

     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' test*.log

     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:x:2098:1000:Eli Smith:/home/eli:/bin/bash

     Alternatively, use ‘-H’, which is a GNU extension:

          grep -H 'eli' /etc/passwd

  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 on some platforms,
     ‘ps’ limits the output 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 non-matching 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. Why does the empty pattern match every input line?

     The ‘grep’ command searches for lines that contain strings that
     match a pattern.  Every line contains the empty string, so an empty
     pattern causes ‘grep’ to find a match on each line.  It is not the
     only such pattern: ‘^’, ‘$’, and many other patterns cause ‘grep’
     to match every line.

     To match empty lines, use the pattern ‘^$’.  To match blank lines,
     use the pattern ‘^[[:blank:]]*$’.  To match no lines at all, use an
     extended regular expression like ‘a^’ or ‘$a’.  To match every
     line, a portable script should use a pattern like ‘^’ instead of
     the empty pattern, as POSIX does not specify the behavior of the
     empty pattern.

  12. How can I search in both standard input and in files?

     Use the special file name ‘-’:

          cat /etc/passwd | grep 'alain' - /etc/motd

  13. Why can't I combine the shell's ‘set -e’ with ‘grep’?

     The ‘grep’ command follows the convention of programs like ‘cmp’
     and ‘diff’ where an exit status of 1 is not an error.  The shell
     command ‘set -e’ causes the shell to exit if any subcommand exits
     with nonzero status, and this will cause the shell to exit merely
     because ‘grep’ selected no lines, which is ordinarily not what you
     want.

     There is a related problem with Bash's ‘set -e -o pipefail’.  Since
     ‘grep’ does not always read all its input, a command outputting to
     a pipe read by ‘grep’ can fail when ‘grep’ exits before reading all
     its input, and the command's failure can cause Bash to exit.

  14. Why is this back-reference failing?

          echo 'ba' | grep -E '(a)\1|b\1'

     This outputs an error message, because the second ‘\1’ has nothing
     to refer back to, meaning it will never match anything.

  15. How can I match across lines?

     Standard grep cannot do this, as it is fundamentally line-based.
     Therefore, merely using the ‘[:space:]’ character class does not
     match newlines in the way you might expect.

     With the GNU ‘grep’ option ‘-z’ (‘--null-data’), each input and
     output "line" is null-terminated; *note Other Options::.  Thus, you
     can match newlines in the input, but typically if there is a match
     the entire input is output, so this usage is often combined with
     output-suppressing options like ‘-q’, e.g.:

          printf 'foo\nbar\n' | grep -z -q 'foo[[:space:]]\+bar'

     If this does not suffice, you can transform the input before giving
     it to ‘grep’, or turn to ‘awk’, ‘sed’, ‘perl’, or many other
     utilities that are designed to operate across lines.

  16. What do ‘grep’, ‘-E’, and ‘-F’ stand for?

     The name ‘grep’ comes from the way line editing was done on Unix.
     For example, ‘ed’ uses the following syntax to print a list of
     matching lines on the screen:

          global/regular expression/print
          g/re/p

     The ‘-E’ option stands for Extended ‘grep’.  The ‘-F’ option stands
     for Fixed ‘grep’;

  17. What happened to ‘egrep’ and ‘fgrep’?

     7th Edition Unix had commands ‘egrep’ and ‘fgrep’ that were the
     counterparts of the modern ‘grep -E’ and ‘grep -F’.  Although
     breaking up ‘grep’ into three programs was perhaps useful on the
     small computers of the 1970s, ‘egrep’ and ‘fgrep’ were deemed
     obsolescent by POSIX in 1992, removed from POSIX in 2001,
     deprecated by GNU Grep 2.5.3 in 2007, and changed to issue
     obsolescence warnings by GNU Grep 3.8 in 2022; eventually, they are
     planned to be removed entirely.

     If you prefer the old names, you can use your own substitutes, such
     as a shell script named ‘egrep’ with the following contents:

          #!/bin/sh
          exec grep -E "$@"

© manpagez.com 2000-2025
Individual documents may contain additional copyright information.