Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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

and

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

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

share|improve this question

2 Answers 2

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.

share|improve this answer
    
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
share|improve this answer
    
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

 
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.