Hello all,

My question is about grep as a command line program...

How can I tell grep to only search inside files that end in ".php"?

The command that I am using now is:
grep -r "some_string" some_directory

Thanks!

-Dave

grep -r --include=*.php "some_string" some_directory

works in GNU grep 2.5.1

post output of `grep --version` and `grep --help` if that doesn't work... there might be another way.

Thanks for the reply Matt. But that didn't seem to work as expected.

I also noticed that there are two versions of grep available on our server:
/usr/bin/grep
/usr/local/bin/grep

If it type: "which grep"
I get: "/usr/bin/grep"

Here is the output of /usr/bin/grep --help

Usage: grep [OPTION]... PATTERN [FILE] ...
Search for PATTERN in each FILE or standard input.
Example: grep -i 'hello world' menu.h main.c

Regexp selection and interpretation:
  -E, --extended-regexp     PATTERN is an extended regular expression
  -F, --fixed-strings       PATTERN is a set of newline-separated strings
  -G, --basic-regexp        PATTERN is a basic regular expression
  -e, --regexp=PATTERN      use PATTERN as a regular expression
  -f, --file=FILE           obtain PATTERN from FILE
  -i, --ignore-case         ignore case distinctions
  -w, --word-regexp         force PATTERN to match only whole words
  -x, --line-regexp         force PATTERN to match only whole lines
  -z, --null-data           a data line ends in 0 byte, not newline

Miscellaneous:
  -s, --no-messages         suppress error messages
  -v, --invert-match        select non-matching lines
  -V, --version             print version information and exit
      --help                display this help and exit
  -Z, --decompress          decompress input before searching (HAVE_LIBZ=1)
      --mmap                use memory-mapped input if possible

Output control:
  -b, --byte-offset         print the byte offset with output lines
  -n, --line-number         print line number with output lines
  -H, --with-filename       print the filename for each match
  -h, --no-filename         suppress the prefixing filename on output
  -q, --quiet, --silent     suppress all normal output
      --binary-files=TYPE   assume that binary files are TYPE
                            TYPE is 'binary', 'text', or 'without-match'.
  -a, --text                equivalent to --binary-files=text
  -I                        equivalent to --binary-files=without-match
  -d, --directories=ACTION  how to handle directories
                            ACTION is 'read', 'recurse', or 'skip'.
  -r, --recursive           equivalent to --directories=recurse.
  -L, --files-without-match only print FILE names containing no match
  -l, --files-with-matches  only print FILE names containing matches
  -c, --count               only print a count of matching lines per FILE
      --null                print 0 byte after FILE name

Context control:
  -B, --before-context=NUM  print NUM lines of leading context
  -A, --after-context=NUM   print NUM lines of trailing context
  -C, --context[=NUM]       print NUM (default 2) lines of output context
                            unless overridden by -A or -B
  -NUM                      same as --context=NUM
  -U, --binary              do not strip CR characters at EOL (MSDOS)
  -u, --unix-byte-offsets   report offsets as if CRs were not there (MSDOS)

`egrep' means `grep -E'.  `fgrep' means `grep -F'.
With no FILE, or when FILE is -, read standard input.  If less than
two FILEs given, assume -h.  Exit status is 0 if match, 1 if no match,
and 2 if trouble.

Report bugs to <bug-gnu-utils@gnu.org>.

Here is the output of /usr/bin/grep --version

grep (GNU grep) 2.4d

Copyright (C) 1988, 1992-1998, 1999 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Here is the output of /usr/local/bin/grep --version

grep version 0.9
/usr/local/bin/grepusage: grep [-[AB] num] [-CEFGHLPRSVZabchilnoqsvwx] [-e patttern] [-f file]

Thanks!
-Dave

Try this; it relies on the 'find' command.

find . -name "*.php" -exec grep -H "some_string" {} \;

Which translates in english to.. search (find) in this folder (.) for files matching the filter ( -name ) *.php [ recursiveness should be default ]; when each file is found, execute grep, look for 'some_string', and pass in the found filename ( where the {} placeholder is ). Because that effectively executes grep once per file ( rather than once for many files ), you need the -H option to force grep to turn on the output of the filename; it wouldn't bother otherwise for a single file grep.

Messy eh? No wonder they put this functionality directly into grep for the next version...

EDIT: By the way, use that with the /usr/bin/grep.

Here's a simpler one in the same vein:

grep "some_string" `find some_folder -name "*.some_extension"`

i.e. grep "cerr" `find . -name "*.cpp"` note backticks (`) rather than single quotes around the find subcommand..

Many thanks Matt for the excellent help!

The command you posted works well:

grep "some_string" `find some_folder -name "*.some_extension"`

But there seems to be a limitation. I found that the command works as expected if used on a directory which does not contain many files. However, when I attempt to use it to search through all files in my site root directory, I get the following error:

/usr/bin/grep: Argument list too long.

My original problem to solve was how to search the contents of all PHP files within a website for a given text string.

Any further advice?

Thank you!
-Dave

lol.. didn't think of that.

did you try the first one I posted? that shouldn't hit the same problem.. because grep is opened with one line of arguement at a time.

otherwise; try this one:

find some_dir -name "*.some_ext" | xargs -l10 grep "some_expr"

looks similar to the find . -name "*.php" -exec grep -H "some_string" {} \; one; but it lets find collect the entire set of files and pipe them to the xargs command, which splits the set into blocks of 10 lines ( controlled using the -l flag ), and calls grep with those blocks of files as the last argument( s )..

with the split line set to 10; this one seems to run much, much faster than the other three ways.. You could change -l10 to be higher or lower, if you set it to 1 though you'll need to add the -H flag to grep again.

That solved my problem! (with a small correction)

I found that your command as posted did not work:

find some_dir -name "*.some_ext" | xargs -l10 grep "some_expr"

I got an error that "-l" was an illegal option. I looked at the man page for xargs and found that it should actually be "-L"

So here's the final command line magic that does exactly what I want:

find some_dir -name "*.some_ext" | xargs -L10 grep "some_expr"

Many thanks once again to Matt for the excellent suggestions!

Regards,
Dave

>>find some_dir -name "*.some_ext" | xargs -l10 grep "some_expr"

This helped. Thanks.

ps: I used unix utils in windows.

Guys is there a way to make the file name appear in color with the last command:

find some_dir -name "*.some_ext" | xargs -L10 grep "some_expr"

?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.