What is the difference between:
grep "string" . -r --include *.pl


grep "string" . -r --include "*.pl"

The latter includes files in subdirectoried while the former not. Why?

  • The difference isn't in grep; it's in the shell. grep never sees the quotes. – Wildcard Jan 11 '17 at 0:08

The * (star, or asterisk) is a special character which is (usually) interpreted by the shell before it is given the command. It is (usually) expanded to all filenames except those with leading dots. See the bash manual about pattern matching for more information.

If placed in quotes the star will not be interpreted by the shell and is given to the command verbatim.

Examples explained. The quoted one:

grep "string" . -r --include "*.pl"

Here grep will receive the option --include with the argument *.pl. That is the 4 character string with the * character as first character. What grep does with that string is entirely up to grep. In this case --include means to only consider files matching the pattern *.pl.

AFAIK behind the scenes gnu grep uses the same pattern matching lib as gnu bash.

The not quoted one:

grep "string" . -r --include *.pl

Here the shell will first expand the pattern *.pl to all filenames ending in .pl. Suppose there are the files foo.pl, bar.pl and baz.pl. After expanding the command line looks like this:

grep "string" . -r --include foo.pl bar.pl baz.pl

Here grep will receive the option --include with the argument foo.pl, followed by the options bar.pl and baz.pl. --include foo.pl means to only consider files matching the pattern foo.pl. Since there are no wildcards in the pattern the only file matching that will be the file named foo.pl.

The options bar.pl and baz.pl means grep will also search in those files, but since they do not match the pattern foo.pl they will be ignored.

  • This is a great observation. I always wondered why grep -r seemed inconsistent but never noticed it was only when I used a *. – j883376 Jul 8 '13 at 8:38

The difference is that if you don't quote the pattern (*.pl) it is expanded by the shell. For example, if you run your grep in a directory that contains a file called foo.pl, since the *pl is expanded by the shell, what grep actually sees is:

grep "string" . -r --include foo.pl

Since you tell it to only include foo.pl it will only search through that one file.

If you quote your pattern, the shell will not expand it and grep gets the correct command, namely

 grep "string" . -r --include *pl
  • peopl will not get expanded by *.pl. – unxnut Jul 7 '13 at 21:35
  • @unxnut good point, answer edited. – terdon Jul 7 '13 at 21:59

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.