Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I am using OS X.

I need to find files in a directory with the .php extension and the string 41 somewhere in the file's contents.

I tried using grep.

grep -R 41 *.php

This however only seemed to find files in the CWD and not in sub directories.

I also tried messing with find.

I wasn't able to figure this out.

What am I doing wrong?

share|improve this question
    
The 41 needs to be in the file name, or its content? –  Daniel Beck May 31 '11 at 6:51
    
@Daniel In the contents, sorry if it wasn't clear. –  alex May 31 '11 at 6:53
    
it does that because you told it to only search all files ending in php in the CWD - mind the expansion precedence... –  Florenz Kley Jan 31 '13 at 1:00

3 Answers 3

up vote 9 down vote accepted

You need both.

find . -name '*.php' -type f -exec grep -q 41 {} \; -print
share|improve this answer
    
+1 Ignacio. Is it possible for it show the excerpt of the file where it found the substring, like grep normally does? Thanks. –  alex May 31 '11 at 6:59
    
Sure. Just remove -q and the -print predicate. –  Ignacio Vazquez-Abrams May 31 '11 at 7:00
    
Thank you. I really need to learn more about these things... –  alex May 31 '11 at 7:01
    
As you do, you'll learn why find . -name '*.php' -type f -print0 | xargs -0 fgrep 41 -- is the next thing that people will suggest to you. –  JdeBP May 31 '11 at 8:37
    
No need for xargs; BSD find understands -exec ... +. –  Ignacio Vazquez-Abrams May 31 '11 at 8:38

in order for grep to work recursively, the argument to grep needs to include the directories it's expected to recurse.

looking at the following files

shiny:t fl$ find .
.
./evenmore
./evenmore/foo.php
./evenmore/inhere.php
./evenmore/no41in.php
./foo.php
./inhere.php
./morestuff
./morestuff/foo.php
./morestuff/inhere.php
./morestuff/no41in.php
./no41in.php
./stuff
./stuff/no41in.php

this does not work:

shiny:t fl$ grep -r 41 *.php
foo.php:41
inhere.php:41

because after path name expansion is done, the shell has processed the asterisk and the command line is now

shiny:t fl$ set -x
shiny:t fl$ grep -r 41 *.php
+ grep -r 41 foo.php inhere.php no41in.php
foo.php:41
inhere.php:41

there is no directory to descend in in the argument handed to grep. This however will descend in all directories present:

shiny:t fl$ grep -r 41 .
./evenmore/foo.php:41
./evenmore/inhere.php:41
./foo.php:41
./inhere.php:41
./morestuff/foo.php:41
./morestuff/inhere.php:41

whether that also processes dot-directories is left as an exercise to the reader :-)

share|improve this answer

If you use ack you can do ack 41 --php.

ack is like grep with built-in highlighting and line numbering and it's designed for searching source code.

share|improve this answer

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.