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,


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

  • 1
    Definitely +1 for making me realize, after all those long years, that grep has a -r option... – DevSolar Apr 23 '10 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 '10 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. – Andy Lester May 3 '10 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. – Daniel Andersson May 11 '12 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. – Daniel Andersson May 11 '12 at 7:05
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
  • in this case xargs might be better than -exec; -exec will spawn one grep process for each file. – quack quixote Apr 23 '10 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 '10 at 8:04
  • How about grep -l instead of grep -q -print? – DevSolar Apr 23 '10 at 8:15
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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