How do I find text within a file and have it search multiple subfolders?
Solution 1
$ find . -type f -print0 | xargs -0 grep foo
$ grep -r foo . # GNU grep only
and in zsh
with setopt extendedglob
,
$ grep foo **/*(.)
Solution 2
There's also ack
, which is designed specifically for this kind of tasks and does subfolder search automatically.
Solution 3
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?)
Solution 4
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.
Related videos on Youtube
tooshel
Updated on September 17, 2022Comments
-
tooshel almost 2 years
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?-
Hello71 over 13 yearsDuh what?
find
only finds file names, not contents. -
geekosaur over 13 yearsEver heard of
xargs
? Or the-exec
primary infind
? -
tooshel over 13 yearsHey 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.
-
geekosaur over 13 yearsSorry, that remark was directed at @Hello71. I'm still getting used to StackExchange etiquette.
-
Vijay about 10 yearsTake a look at this post:theunixshell.blogspot.in/2014/03/…
-
Batfan over 8 yearsfind * is always a bad idea. See the section "NON-BUGS" at linux.die.net/man/1/find
-
-
Gilles 'SO- stop being evil' over 13 years
find … -print0 | xargs -0 …
copes with arbitrary file names. All POSIX.2004-compliant implementations offind
allowfind … -exec … {} +
, which invokes the command with multiple files at once. A better command isfind . -type f -exec grep test /dev/null {} +
; the addition of/dev/null
is so thatgrep
will consistently print the file name when it finds a match. -
Gilles 'SO- stop being evil' over 13 yearsBetter:
find . -type f -print0 | xargs -0 grep /dev/null foo
, so thatgrep
always prints the matching file name. Orfind . -type f -exec grep /dev/null {} +
, for implementations that have caught up with POSIX.2004 (which excludes OpenBSD at the moment). -
tooshel over 13 yearsStill 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 over 13 yearsYeah, apparently not everyone has the fancy version of grep.
-
geekosaur over 13 yearsBecause traditional
grep
didn't have it (the idea was that if you wanted recursion, you usedfind
withgrep
) and adding it after the fact to systems that have been working for years could break things. (GNUgrep
doesn't behave quite identically to e.g. System Vgrep
.) -
simon over 13 years@tooshel - didn't realise the non-GNU
grep
doesn't have that option. updated my answer :) -
tooshel over 13 years-bash: ack: command not found
-
tooshel over 13 yearsOkay, I read the instructions to install ack . . . and I just tossed it in /bin so everyone can use it. Was that a bad idea?
-
simon over 13 years@tooshel: only if you don't want everyone to be able to use it...!
-
KillerSpaz over 10 yearsAn there is also
ag
which is way faster thanack
.