Find words in many files

2

2

I am looking for this struct messages_sdd_t and I need to search through a lot of *.c files to find it. However, I can't seen to find a match as I want to exclude all the words 'struct' and 'messages_sdd_t'. As I want to search on this only 'struct messages_sdd_t' The reason for this is, as struct is used many times and I keep getting pages or search results.

I have been doing this without success:

find . -type f -name '*.c' | xargs grep 'struct messages_sdd_t'

and this

find . -type f -name '*.c' | xargs egrep -w 'struct|messages_sdd_t'

Many thanks for any suggestions,

ant2009

Posted 2010-04-23T05:22:35.697

Reputation: 2 595

Answers

5

Use ack:

ack "struct messages_sdd_t" *.c

It is recoursive by default and it is a lot faster than grep (according to my observation) when searching trough a directory containing tons of source code.

If you don't want to use ack, grep should be fine too:

grep -r "struct messages_sdd_t" *.c

Ivan Petrushev

Posted 2010-04-23T05:22:35.697

Reputation: 1 591

1Definitely +1 for making me realize, after all those long years, that grep has a -r option... – DevSolar – 2010-04-23T08:03:01.633

"grep -r" is a really good answer. The problem with find | xargs is that if there are many files, you will get an "argument list too long" error message. You can use the -n switch for xargs to avoid this, but then you should set the -H switch for grep so you can be sure that it prefixes the filename. There is one advantage of using "find | xargs" instead of "grep -r": you can make arbitrary filter for the files you want to search. – petersohn – 2010-04-23T08:25:28.437

Ack recognizes C as a filetype. Use "ack 'struct messages_sdd_t' --cc", and it will find all C files, including .h header files. – Andy Lester – 2010-05-03T18:56:01.383

@petersohn: xargs does not fail in this way. It uses the system value of maximum argument length and splits accordingly. Run xargs --show-limits to see what it uses on your specific system. If one needs to use find, it is also good to see the -exec command {} + construct in the manual which will more or less emulate xargs directly in the find command, with as few sub process invocations as possible. – Daniel Andersson – 2012-05-11T06:54:17.930

@ant2009: The given answer is incorrect since it will not search recursively when given file names as arguments like this. It will only search through the .c files in the current directory, not sub directories. – Daniel Andersson – 2012-05-11T07:05:27.197

1

find . -type f -name '*.c' -exec grep 'struct\s\+messages_sdd_t' {} \;

Or if you only care about the filename:

find . -type f -name '*.c' -exec grep -q 'struct\s\+messages_sdd_t' {} \; -print

Ignacio Vazquez-Abrams

Posted 2010-04-23T05:22:35.697

Reputation: 100 516

in this case xargs might be better than -exec; -exec will spawn one grep process for each file. – quack quixote – 2010-04-23T07:11:36.617

No, exec doesn't do that - {} \; does. If you use {} +, multiple files will be processed by a single grep process. – DevSolar – 2010-04-23T08:04:06.297

How about grep -l instead of grep -q -print? – DevSolar – 2010-04-23T08:15:22.460

1

grep -R --include='*.c' 'struct messages_sdd_t' .

This will search recursively and use grep itself to pick only .c files.

Consider adding -H to always write the file name with the line match.

Daniel Andersson

Posted 2010-04-23T05:22:35.697

Reputation: 20 465