Next: Performance, Previous: Regular Expressions, Up: grep [Contents][Index]
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.
See 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.
See Invoking grep
, for more details about
how to invoke grep
.
Here are some common questions and answers about grep
usage.
grep -l 'main' test-*.c
lists names of ‘test-*.c’ files in the current directory whose contents mention ‘main’.
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
grep -- '--cut here--' *
searches for all lines matching ‘--cut here--’.
Without --,
grep
would attempt to parse ‘--cut here--’ as a list of
options, and there would be similar problems with any file names
beginning with ‘-’.
Alternatively, you can prevent misinterpretation of leading ‘-’ by using -e for patterns and leading ‘./’ for files:
grep -e '--cut here--' ./*
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’.
grep -C 2 'hello' test*.log
prints two lines of context around each matching line.
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
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.
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,
or the -s or --no-messages option.
‘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.
grep 'paul' /etc/motd | grep 'franc,ois'
finds all lines that contain both ‘paul’ and ‘franc,ois’.
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 the command ‘grep -f /dev/null’.
Use the special file name ‘-’:
cat /etc/passwd | grep 'alain' - /etc/motd
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.
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; see 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.
grep
, fgrep
, and egrep
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
fgrep
stands for Fixed grep
;
egrep
stands for Extended grep
.
Next: Performance, Previous: Regular Expressions, Up: grep [Contents][Index]