309
votes

How can I get grep to display the filename before the matching lines in its output?

6
pls tell your grep version grep --version - Kent
kent, grep --version is that the command to be used to know the grep version? If so, its not working. Couldnt find any other command to know the grep version. - Vivek
good question but 'Os version' is a confusing example filename - HaveAGuess
The OS & version is irrelevant here. - MD XF
grep 'pattern' * - user0

6 Answers

466
votes

Try this little trick to coax grep into thinking it is dealing with multiple files, so that it displays the filename:

grep 'pattern' file /dev/null

To also get the line number:

grep -n 'pattern' file /dev/null
326
votes

If you have the options -H and -n available (man grep is your friend):

$ cat file
foo
bar
foobar

$ grep -H foo file
file:foo
file:foobar

$ grep -Hn foo file
file:1:foo
file:3:foobar

Options:

-H, --with-filename

Print the file name for each match. This is the default when there is more than one file to search.

-n, --line-number

Prefix each line of output with the 1-based line number within its input file. (-n is specified by POSIX.)

-H is a GNU extension, but -n is specified by POSIX

49
votes

No trick necessary.

grep --with-filename 'pattern' file

With line numbers:

grep -n --with-filename 'pattern' file
6
votes

How about this, which I managed to achieve thanks, in part, to this post.

You want to find several files, lets say logs with different names but a pattern (e.g. filename=logfile.DATE), inside several directories with a pattern (e.g. /logsapp1, /logsapp2). Each file has a pattern you want to grep (e.g. "init time"), and you want to have the "init time" of each file, but knowing which file it belongs to.

find ./logsapp* -name logfile* | xargs -I{} grep "init time" {} \dev\null | tee outputfilename.txt

Then the outputfilename.txt would be something like

./logsapp1/logfile.22102015: init time: 10ms
./logsapp1/logfile.21102015: init time: 15ms
./logsapp2/logfile.21102015: init time: 17ms
./logsapp2/logfile.22102015: init time: 11ms

In general

find ./path_pattern/to_files* -name filename_pattern* | xargs -I{} grep "grep_pattern" {} \dev\null | tee outfilename.txt

Explanation:

find command will search the filenames based in the pattern

then, pipe xargs -I{} will redirect the find output to the {}

which will be the input for grep ""pattern" {}

Then the trick to make grep display the filenames \dev\null

and finally, write the output in file with tee outputfile.txt

This worked for me in grep version 9.0.5 build 1989.

1
votes

This is a slight modification from a previous solution. My example looks for stderr redirection in bash scripts: grep '2>' $(find . -name "*.bash")

-8
votes
grep 'search this' *.txt

worked for me to search through all .txt files (enter your own search value, of course).