Reputation: 1574
Here is the code at the bash shell. How is the file mask supposed to be specified, if not this way? I expected both commands to find the search expression, but it's not happening. In this example, I know in advance that I prefer to restrict the search to python source code files only, because unqualified searches are silly time wasters.
So, this works as expected:
grep -rni '/home/ga/projects' -e 'def Pr(x,u,v)'
/home/ga/projects/anom/anom.py:27:def Pr(x,u,v): blah, blah, ...
but this won't work:
grep --include=\*.{py} -rni '/home/ga/projects' -e 'def Pr(x,u,v)'
I'm using GNU grep
version 2.16.
Upvotes: 3
Views: 310
Reputation: 793
Your command fails because of the braces '{}'. It will search for it in the file name. You can create a file such as 'myscript.{py}' to convince yourself. You'll see it will appear in the results.
The correct option parameter would be '*.py'
or the equivalent \*.py
. Either way will protect it from being (mis)interpreted by the shell.
On the other side, I can only advise to use the command find for such jobs :
find /home/ga/projects -regex '.*\.py$' -exec grep -e "def Pr(x,u,v)" {} +
That will protect you from hard to understand shell behaviour.
Upvotes: 2
Reputation: 19339
Try like this (using quotes to be safe; also better readability than backslash escaping IMHO):
grep --include='*.py' ...
your \*.{py}
brace expansion usage isn't supported at all by grep
. Please see the comments below for the full investigation regarding this. For the record, blame this answer for the resulting brace wars ;)
By the way, the brace expansion works generally fine in Bash. See mklement0 answer for more details.
Ack. As an alternative, you might consider switching to ack
instead from now on. It's a tool just like grep
, but fully optimized for programmers.
It's a great fit for what you are doing. A nice quote about it:
Every once in a while something comes along that improves an idea so much, you can't ignore it. Such a thing is
ack
, thegrep
replacement.
Upvotes: 1
Reputation: 439257
--include=\*.{py}
looks like a broken attempt to use brace expansion (an unquoted {...}
expression).
However, for brace expansion
to occur in bash
(and ksh
and zsh
), you must either have:
a list of at least 2 items, separated with ,
; e.g. {py,txt}
, which expands to 2 arguments, py
and txt
.
or, a range of items formed from two end points, separated with ..
; e.g., {1..3}
, which expands to 3 arguments, 1
, 2
, and 3
.
Thus, with a single item, simply do not use brace expansion:
--include=\*.py
If you did have multiple extensions to consider, e.g., *.py
as well as *.pyc
files, here's a robust form that illustrates the underlying shell features:
'--include=*.'{py,pyc}
Here:
{...}
contains a 2-item list.{...}
directly follows the literal (single-quoted) string --include=*.
, the results of the brace expansion include the literal part.grep
, with the following literal content:
--include=*.py
--include=*.pyc
Upvotes: 3