Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I'm looking for a function name and the folder structure is deep and there are a lot of files to look though.

Usually I go with something like find * | grep functionname but is that the best way?

share|improve this question
    
Duh what? find only finds file names, not contents. –  Hello71 Mar 12 '11 at 1:44
    
Ever heard of xargs? Or the -exec primary in find? –  geekosaur Mar 12 '11 at 1:51
    
Hey man, I said that's what I used, not that it worked! Why do you think I'm asking? Plus, it was "something like" because I could never get it to work and had to google around for the xargs part. –  tooshel Mar 14 '11 at 21:49
    
Sorry, that remark was directed at @Hello71. I'm still getting used to StackExchange etiquette. –  geekosaur Mar 14 '11 at 21:58
    
Take a look at this post:theunixshell.blogspot.in/2014/03/… –  Vijay 2 days ago
add comment

7 Answers

$ find . -type f -print0 | xargs -0 grep foo
$ grep -r foo . # GNU grep only

and in zsh with setopt extendedglob,

$ grep foo **/*(.)
share|improve this answer
    
Better: find . -type f -print0 | xargs -0 grep /dev/null foo, so that grep always prints the matching file name. Or find . -type f -exec grep /dev/null {} +, for implementations that have caught up with POSIX.2004 (which excludes OpenBSD at the moment). –  Gilles Mar 12 '11 at 16:03
    
Still can't believe there isn't an easier way to do this. And I tried the "grep -r" and it didn't work. Why is it only GNU grep only and why isn't that on more systems? –  tooshel Mar 14 '11 at 21:51
1  
Because traditional grep didn't have it (the idea was that if you wanted recursion, you used find with grep) and adding it after the fact to systems that have been working for years could break things. (GNU grep doesn't behave quite identically to e.g. System V grep.) –  geekosaur Mar 14 '11 at 21:58
add comment

There's also ack, which is designed specifically for this kind of tasks and does subfolder search automatically.

share|improve this answer
    
An there is also ag which is way faster than ack. –  mmoya Nov 15 '13 at 12:29
add comment

As an alternative to the find | xargs responses, you might consider using ctags since you say you are searching not for text, but specifically for function names.

To do this you would run ctags against your source to create a TAGS file, and then run your grep against the TAGS file which will spit out lines in the following format:

{tagname}<Tab>{tagfile}<Tab>{tagaddress}

Where tagname will contain the function name, tagfile is the file it is in, and tagaddress will be a vi command to get to that line. (Could be a just a line number.)

(Is there an easy way to do something similar with the various indices that eclipse builds, or to just query the eclipse database?)

share|improve this answer
add comment

what's wrong with grep -r (== grep --recursive)? Am I missing something here?

(+1 for ack too -- I regularly use both)

edit: I found an excellent article detailing the possibilities and pitfalls if you don't have GNU grep here. But, seriously, if you don't have GNU grep available, getting ack is even more highly recommended.

share|improve this answer
    
Yeah, apparently not everyone has the fancy version of grep. –  tooshel Mar 14 '11 at 21:54
    
@tooshel - didn't realise the non-GNU grep doesn't have that option. updated my answer :) –  simon Mar 15 '11 at 1:40
    
-bash: ack: command not found –  tooshel Mar 17 '11 at 22:05
    
Okay, I read the instructions to install ack . . . and I just tossed it in /bin so everyone can use it. Was that a bad idea? –  tooshel Mar 17 '11 at 22:14
    
@tooshel: only if you don't want everyone to be able to use it...! –  simon Mar 18 '11 at 2:52
add comment

find . | xargs grep will fail on filenames with spaces:

> echo test > "a b c"
> find . | xargs grep test
grep: ./a: No such file or directory
grep: b: No such file or directory
grep: c: No such file or directory

Note that even -print0 has this problem.

It's better in my opinion to use -exec grep with find which will handle all filenames internally and avoid this problem:

> find . -exec grep test {} \;
test
>
share|improve this answer
    
find … -print0 | xargs -0 … copes with arbitrary file names. All POSIX.2004-compliant implementations of find allow find … -exec … {} +, which invokes the command with multiple files at once. A better command is find . -type f -exec grep test /dev/null {} +; the addition of /dev/null is so that grep will consistently print the file name when it finds a match. –  Gilles Mar 12 '11 at 16:01
add comment

If your disks are fast you may want to parallelize the grep:

find . -type f -print0 | parallel -0 grep foo

Watch the intro video to learn more about GNU Parallel: http://www.youtube.com/watch?v=OpaiGYxkSuQ

share|improve this answer
add comment

$ find -type f -print0 | xargs -r0 grep foo

-r in xargs avoids executing the command if there wasn't input. It's a GNU extension.

There is also ag which is specifically designed for this and way better than ack. It's available in recent Debian/Ubuntu versions in package silversearcher-ag.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.