Combining 'find' and 'grep' or searching in general

Combining 'find' and 'grep' or searching in general

Post by Warren Porte » Tue, 24 Feb 1998 04:00:00



When I run a command like the following:
    find . -name *.c -exec grep 'looking for text' {} \; |tee my.txt

grep will show me the line containing 'looking for text', but it won't
tell me the name of the file it found it in, unlike running grep
standalone.  Any suggestions?

TIA

 
 
 

Combining 'find' and 'grep' or searching in general

Post by Thomas Thyber » Tue, 24 Feb 1998 04:00:00


: When I run a command like the following:
:     find . -name *.c -exec grep 'looking for text' {} \; |tee my.txt
:
: grep will show me the line containing 'looking for text', but it won't
: tell me the name of the file it found it in, unlike running grep
: standalone.  Any suggestions?

% find . -name *.c -exec grep 'looking for text' {} /dev/null \; |tee my.txt

----------------------------------------------------^^^^^^^^^

Add /dev/null s? grep thinks it has more than one file and it will
report the filename also.

/TT

--
Use this          tt                | Some addresses to keep email



 
 
 

Combining 'find' and 'grep' or searching in general

Post by Kaz Kylhe » Tue, 24 Feb 1998 04:00:00




Quote:>When I run a command like the following:
>    find . -name *.c -exec grep 'looking for text' {} \; |tee my.txt

>grep will show me the line containing 'looking for text', but it won't
>tell me the name of the file it found it in, unlike running grep
>standalone.  Any suggestions?

The behavior of grep is such that if it is invoked on one file, it will
suppress the output of the filename. The age old trick is taht you must give
it two filenames, the first of which is /dev/null.

Also, instead of separately invoking grep for each matching file, why
not collect multiple matching files into a larger command line? This
is more efficient because you launch grep fewer times.

        find . -name '*.c' -print | xargs grep /dev/null | tee my.txt

The xargs command takes lines of input and builds large command lines
from them.

Note that I put the *.c pattern in quotes. If you don't put it into quotes,
and there are .c files in the current directory, then they will be expanded,
whereas you want to pass the original pattern to find. It's a good habit
to always use quotes with find.

 
 
 

Combining 'find' and 'grep' or searching in general

Post by rang » Tue, 24 Feb 1998 04:00:00





> : When I run a command like the following:
> :     find . -name *.c -exec grep 'looking for text' {} \; |tee my.txt
> :
> : grep will show me the line containing 'looking for text', but it won't
> : tell me the name of the file it found it in, unlike running grep
> : standalone.  Any suggestions?

> % find . -name *.c -exec grep 'looking for text' {} /dev/null \; |tee my.txt

> ----------------------------------------------------^^^^^^^^^

> Add /dev/null s? grep thinks it has more than one file and it will
> report the filename also.

What you really want is xargs:

( find . -name "*.c" | xargs grep 'looking for text' ) | tee my.txt

This has the additional advantage of not creating a new shell for each
grep against a file.

HTH,


 
 
 

Combining 'find' and 'grep' or searching in general

Post by Icarus Sparr » Thu, 26 Feb 1998 04:00:00






>> : When I run a command like the following:
>> :     find . -name *.c -exec grep 'looking for text' {} \; |tee my.txt
>> :
>> : grep will show me the line containing 'looking for text', but it won't
>> : tell me the name of the file it found it in, unlike running grep
>> : standalone.  Any suggestions?

>What you really want is xargs:

>( find . -name "*.c" | xargs grep 'looking for text' ) | tee my.txt

>This has the additional advantage of not creating a new shell for each
>grep against a file.

The advantage is that it doesn't create a new grep for each filename.

Actually you don't want the brackets, as they typically force another shell,
you do want a '-print' arguement for find for portability, and you DO WANT
the /dev/null arguement to grep. The reason for the latter is that 'xargs'
reads its input as lines, groups them into chunks, and then executes its
arguements with the file names added. Consider a list of files which is
just one filename long, or a list of files which is one filename bigger
than a chunk.

If you have a version of 'find' which supports the '-print0' and a version
of xargs which supports the '-0' then you should use them, otherwise filenames
with embedded newlines will cause problems. So the correct advice is

find . -name '*.c' -print0 | xargs -0 grep 'looking for text' /dev/null | tee my.txt

or

find . -name '*.c' -print | xargs grep 'looking for text' /dev/null | tee my.txt

Icarus

 
 
 

Combining 'find' and 'grep' or searching in general

Post by Glenn Evan » Sat, 28 Feb 1998 04:00:00



> When I run a command like the following:
>     find . -name *.c -exec grep 'looking for text' {} \; |tee my.txt

> grep will show me the line containing 'looking for text', but it won't
> tell me the name of the file it found it in, unlike running grep
> standalone.  Any suggestions?

Grep will only display the filenames if searching more than one file at a
time. Because you're using find with \; you're passing the files through
to grep one at a time.  If you instead use \+, you will pass the files in
a group, but won't give arg list too long.
If all you want is the filename, use grep -l.

More later...

 
 
 

Combining 'find' and 'grep' or searching in general

Post by Sitaram Chamar » Sat, 28 Feb 1998 04:00:00


On Mon, 23 Feb 1998 11:29:31 -0600, Warren Porter


>When I run a command like the following:
>    find . -name *.c -exec grep 'looking for text' {} \; |tee my.txt

>grep will show me the line containing 'looking for text', but it won't
>tell me the name of the file it found it in, unlike running grep
>standalone.  Any suggestions?

use xargs
    find . -name "*.c" -print | xargs grep 'looking for text' | less

xargs tries to run the grep command with more than one argument
(actually as many as can fit on one "command line" - whatever that
is).

Another common trick is to add
    /dev/null
just before the
    \;
in your command.  That makes grep think its dealing with more than
one file argument and forces it to put the filename before the
match.

However, xargs is faster.  As long as the filenames are clean (no
spaces etc inside filenames and so on).

 
 
 

1. Sting search w/o 'find' or 'du'

I'm in a Unix course and I have a question. I need to write a
replacement 'find' command and I've got everything done but one. Given
that I have a list of files in a dir stored in a string array, how do
I search each array element to see if it contains a given substring? I
have to be able to determine if the sub string is contained within the
array element in any fashion (begin, middle, end, etc.)

I would appreciate any help with this. Either post here or email
directly to me. Thanks.

2. Whats wrong with this script?

3. How to combine 'mbuild' and 'tmCC' to compile program?

4. PPP problems, damnit!

5. grep octal value (grep '\0145' /tmp/test) doesn't work !!

6. XDM/KDM question.

7. 'Find' 'Updatedb' or find database replacement for Solaris 2.X?

8. "Expiring" nfs-files ???

9. 'diff' option like 'grep -q'?

10. Q: grep 'foo' NOT followed by 'bar'

11. What's 'side effects' of Ksh built-ins?

12. Why did 'nobody' do a 'find'