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,

3 Answers 3

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

5
  • 1
    Definitely +1 for making me realize, after all those long years, that grep has a -r option...
    – DevSolar
    Apr 23, 2010 at 8:03
  • "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
    Apr 23, 2010 at 8:25
  • Ack recognizes C as a filetype. Use "ack 'struct messages_sdd_t' --cc", and it will find all C files, including .h header files. May 3, 2010 at 18:56
  • @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. May 11, 2012 at 6:54
  • @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. May 11, 2012 at 7:05
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
3
  • in this case xargs might be better than -exec; -exec will spawn one grep process for each file. Apr 23, 2010 at 7:11
  • No, exec doesn't do that - {} \; does. If you use {} +, multiple files will be processed by a single grep process.
    – DevSolar
    Apr 23, 2010 at 8:04
  • How about grep -l instead of grep -q -print?
    – DevSolar
    Apr 23, 2010 at 8:15
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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .