Search code examples
bashgrepglob

Globbing syntax (actually `brace expansion`) with grep: Why doesn't this work?


I'm trying to find all of the instances of a function while also improving my understanding of grep and globbing. However, I can't figure out what I'm misunderstanding.

For example, if I don't glob, and I want to search for a string in files ending in Rmd, I can get the following results

$ grep -rl --include="*Rmd" "plotRFPByPosition" .
./R_notebooks/detecting_stall_sites.Rmd
./R_notebooks/effects_of_data_filtering.Rmd
./R_notebooks/impact_of_ramp.Rmd
./Paper/final_analyses_and_plots.Rmd
$

Similarly for files ending in R, I can get

$ grep -rl --include="*R" "plotRFPByPosition" .
./R_notebooks/helperFunctions.R
./Paper/R_notebooks/helperFunctions.R
$

But if I want to look for files ending in either Rmd or R, this doesn't return anything (not even the previous results.

$ grep -rl --include="*{Rmd,R}" "plotRFPByPosition" .
$ 

I've also tried --include="{*Rmd,*R}" and --include="{Rmd,R}" but none of these work.

What simple aspect about globbing do I misunderstand?


Solution

  • Brace expansion is a separate step from globbing, rather than part of the glob operation; it isn't performed by fnmatch() or glob(), the two C functions most commonly used for glob-type operations (by programs other than shells, which typically include their own extended globbing engines).

    You can use it here, by taking the braces out of quotes:

    grep -rl --include="*"{Rmd,R} plotRFPByPosition
    

    will be rewritten by the shell (performing brace expansion) into:

    grep -rl --include="*"Rmd --include="*"R plotRFPByPosition
    

    ...after which point grep itself will presumably use glob(), fnmatch() or similar to filter for files matching either of those patterns.