Strange issue when running grep with --include option
Here's the code in bash shell. How should the file mask be specified, if not? I expected both teams to find the search expression, but it won't. In this example, I know ahead of time that I prefer to limit the search to only python-based source code files, because unqualified searches are silly time breaks.
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 it won't work:
grep --include=\*.{py} -rni '/home/ga/projects' -e 'def Pr(x,u,v)'
I am using GNU grep
version 2.16.
source to share
--include=\*.{py}
looks like a broken attempt at using parenthesis expansion ( unquoted expression {...}
).
However, for extension extensions
to occur in bash
(and ksh
and zsh
), you must either have:
-
a list of at least 2 items, separated
,
; for example{py,txt}
, which expands to 2 arguments,py
andtxt
. -
or, a range of elements formed from two endpoints separated
..
; for example,{1..3}
which is expandable to 3 arguments1
,2
and3
.
So, with one element, just don't use parenthesis expansion :
--include=\*.py
If you have multiple extensions to consider, for example, *.py
as well as files *.pyc
, here is a robust form that illustrates the basic functionality of the shell:
'--include=*.'{py,pyc}
Here:
- Brace expansion is applied because it
{...}
contains a list of 2 elements. - Since it
{...}
immediately follows a literal (single quote) string--include=*.
, parenthesis expansion results include the literal part. - Hence, the 2 arguments are ultimately passed in
grep
with the following literal:-
--include=*.py
-
--include=*.pyc
-
source to share
Your command doesn't work because of the '{}' brackets. It will look for it in the filename. You can create a file like "myscript. {Py}" to convince yourself. You will see it appear in the results.
The correct parameter parameter will be '*.py'
or equivalent \*.py
. In any case, this will protect it from (interpretation of) the shell by the shell.
On the other hand, I can only recommend using the find command for jobs like this:
find /home/ga/projects -regex '.*\.py$' -exec grep -e "def Pr(x,u,v)" {} +
This will protect you from having a hard time understanding shell behavior.
source to share
Try this (using quotes to be safe and also better readability than backslashes IMHO):
grep --include='*.py' ...
your extension extension is \*.{py}
not supported at all grep
. Please see the comments below for a full investigation of this. For the record, blame this answer as a result of coalescing wars;)
By the way, bracket expansion usually works fine in Bash. See mklement0 for details .
Ack . Alternatively, you can upgrade to ack
. It is a tool similar to grep
but fully optimized for programmers.
This is great for what you are doing. Nice quote on this:
From time to time, something comes along that enhances the idea so much, you cannot ignore it. Such a thing
ack
, a replacementgrep
.
source to share