- Stop after first match
- Print only filename if match
- Find unmatched files
- Show line number of matched lines
- Don’t output filename when grep multiple files
- Search in “binary” files
- Search in directories
- Ignore case when search
- The pattern to search begins with - (hyphen)
- Use pattern file
- Print only count of matching lines
First, grep –help lists most of its options, which is the go-to command for most grep questions.
Like most CLI tools, options of grep can be combined.
For example, -io
is same as -i -o
, -A3
is same as -A 3
.
Also, the options can be anywhere in the command.
$ grep hello a.txt -i --color
Stop after first match
$ grep -m 1 search-word file
-m, –max-count=NUM stop after NUM matches
Only print the 1000th match.
$ grep -m1000 search-word file | tail -n1
Print only filename if match
$ grep -l search-word *.txt
-l, –files-with-matches print only names of FILEs containing matches
It’s useful when you grep lots of files and only care about names of matched files.
Find unmatched files
-L, –files-without-match print only names of FILEs containing no match
-L
is the opposite of -l
option.
It outputs the files which don’t contain the word to search.
$ grep -L search-word *.txt
Show line number of matched lines
$ grep -n search-word file
-n, –line-number print line number with output lines
Don’t output filename when grep multiple files
When grep multiple files, by default filename is included in the output. Like,
$ grep hello *.txt
a.txt:hello
b.txt:hello
Use -h
to not output filenames.
$ grep -h hello *.txt
hello
hello
-h, –no-filename suppress the file name prefix on output
Search in “binary” files
Sometimes, a text file may contains a few non-printable characters, which makes grep consider it as a “binary” file. grep doesn’t print matched lines for a “binary” file.
$ printf "hello\000" > test.txt
$ grep hello test.txt
Binary file test.txt matches
Use -a
to let grep know the file should be seen as a “text” file.
$ grep -a hello test.txt
hello
-a, –text equivalent to –binary-files=text
Search in directories
-r, –recursive like –directories=recurse
-R, –dereference-recursive likewise, but follow all symlinks
Without specifying a directory, grep searches in current working directory by default.
$ grep -R hello
b.md:hello
a.txt:hello
Specify directories.
$ grep -R hello tmp/ tmp2/
tmp/b.md:hello
tmp/a.txt:hello
tmp2/b.md:hello
tmp2/a.txt:hello
–include=FILE_PATTERN search only files that match FILE_PATTERN
Use --include
to tell grep the pattern of the filenames you’re interested in.
$ grep -R hello --include="*.md"
b.md:hello
Ignore case when search
-i, –ignore-case ignore case distinctions
$ grep -i Hello a.txt
hello
HELLO
The pattern to search begins with - (hyphen)
$ grep -- -hello a.txt
-hello
To know what -L
option does.
$ grep --help | grep -- -L
-L, --files-without-match print only names of FILEs containing no match
Use pattern file
-f FILE, –file=FILE Obtain patterns from FILE, one per line. If this option is used multiple times or is combined with the -e (–regexp) option, search for all patterns given. The empty file contains zero patterns, and therefore matches nothing.
$ cat test.txt
111
222
333
$ cat patterns.txt
111
333
$ grep -f patterns.txt test.txt
111
333
NOTE: Do not put an empty line, i.e. a line with \n
only, in the pattern file.
Otherwise, the pattern file would match every line, since every line contains \n
as
its last character. It’s easy to make a mistake to put empty lines in the end of the
pattern file.
Print only count of matching lines
Use -c
, or --count
to print only count of matching lines.
For example, below command line is to find out the count of <OrderLine>
tag in files of current directory.
$ grep "<OrderLine>" -c -R .
It outputs like below.
./order-1.xml:3
./order-2.xml:9
./order-3.xml:1
To sort the output, use command like below.
$ grep "<OrderLine>" -c -R . | sort -t : -k 2
./order-3.xml:1
./order-1.xml:3
./order-2.xml:9