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.

+3


source to share


3 answers


--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

    and txt

    .

  • or, a range of elements formed from two endpoints separated ..

    ; for example, {1..3}

    which is expandable to 3 arguments 1

    , 2

    and 3

    .

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

+3


source


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.

+2


source


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 replacement grep

.

+1


source







All Articles