LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   Find/grep command to find matching files, print filename, then print matching content (http://www.linuxquestions.org/questions/programming-9/find-grep-command-to-find-matching-files-print-filename-then-print-matching-content-328036/)

stefanlasiewski 05-28-2005 03:01 PM

Find/grep command to find matching files, print filename, then print matching content
 
I'm looking for a find command which will do the following:
  • Find files that match some criteria
  • Grep for some text in those files
  • If grep finds matching text, print the filename, and then print the matching lines
Here's an example of what I am looking for:

./dir1/filename1
hello world
hello universe
./filename2
# Prints "hello penguin"
if [ $answer -eq "hello penguin" ]; then
./dir1/dir2/dir3/filename3
Post written by jellohellofellow on Aug 3, 2004

Seems simple, right? But I haven't found anything that does what I want.

Most people do this:

find . -type f |xargs grep hello

But I'm looking for a method that doesn't use xargs.

I see this alot:

find . -exec grep hello {} \; -print

But that command prints the results of 'grep hello' before it prints the filename, like this:

hello world
hello universe
./dir1/filename1
# Prints "hello penguin"
if [ $answer -eq "hello penguin" ]; then
./filename2
./dir1/dir2/dir3/filename3
Post written by jellohellofellow on Aug 3, 2004
./dir1/dir2/dir3/filename3

This is messy.

On most Unix distros, you can do this:

find . -exec grep -l hello {} \;

However, not all flavors of grep support the -l (--files-with-matches) flag. Also, this command only prints the matching files; it doesn't print the lines that match.

ToniT 05-28-2005 03:43 PM

How about
Code:

find . -exec grep -Hn hello {} \;
?

stefanlasiewski 05-28-2005 04:35 PM

Thanks for the help, but I'm not sure if that will work. I'm working with a very primitive form of grep that doesn't support alot of the fancy features in GNU Grep.

I'll try it when I get back.

I'm working with Solaris 8 right now, but I'm also looking for a universal solution that works on AIX, HPUX, Alpha, and most flavors of Linux. GNU did it the right way. All the other vendors should follow GNU's lead.

ToniT 05-28-2005 04:53 PM

Are you sure there is no GNU version of grep available already (eg. with a name ggrep)?

I tested with the most archaic grep I could found
(the binary contains comment "SunOS 5.8 Generic February 2000") and
I got the command
Code:

find . -exec grep -n hello /dev/null {} \;
to do the same thing as my previous example in Linux systems.


Other solution is to compile working grep by yourself:
http://packages.debian.org/unstable/base/grep

stefanlasiewski 05-29-2005 04:07 PM

That works great! Thanks.

Clever trick with the /dev/null . Without it, I don't get the filename, just the line numbers. With /dev/null, it looks like grep sees at least two files and knows to print the name of both files.

Thanks a bunch!

jonaskoelker 05-29-2005 05:07 PM

I know it's overkill, but this should also work

$ find / exec grepper.sh pattern {} \;
grepper.sh:
Code:

if grep "$1" "$2" &> /dev/null; then
    echo "$1"
    grep "$1" "$2"

add grep args to taste ;)

hth --Jonas

Sukhwinder Singh 09-18-2006 03:02 AM

Find the matching pattern and print it
 
My solution is:

#find / -print -exec grep 'hello' {} \;

digitalDNA 01-06-2008 02:10 AM

Hello,

I use this form:

find . -exec grep -H -n 'hello' {} \;

-H -n display filename and line number


If you need another 'piped' grep, you can do this:

find . -exec grep -H -n 'hello' {} \; | grep 'line should contain this too'




Best Regards.

boskyo 12-18-2013 05:36 PM

Using find & xargs w/ grep
 
I use find with xargs and it works well. Though it is a bit to type it can have further pipes attached at the end.

Leave off the -i and -n as desired.

Here is an example:

>> find . -name '*.[ch]' -print0 | xargs -0 -I file grep -inH 'gpio_request' file
./adi/adv7511_core-adi-fork-drm.c:859: ret = devm_gpio_request_one(&i2c->dev, adv7511->gpio_pd,
./via-camera.c:199: ret = gpio_request(cam->power_gpio, "viafb-camera");
./via-camera.c:204: ret = gpio_request(cam->reset_gpio, "viafb-camera");


All times are GMT -5. The time now is 01:52 AM.