Display filename before matching line
UnixGrepUnix Problem Overview
How can I get grep
to display the filename before the matching lines in its output?
Unix Solutions
Solution 1 - Unix
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
Solution 2 - Unix
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
Solution 3 - Unix
No trick necessary.
grep --with-filename 'pattern' file
With line numbers:
grep -n --with-filename 'pattern' file
Solution 4 - Unix
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.
Solution 5 - Unix
This is a slight modification from a previous solution. My example looks for stderr redirection in bash scripts:
grep '2>' $(find . -name "*.bash")
Solution 6 - Unix
grep 'search this' *.txt
worked for me to search through all .txt files (enter your own search value, of course).