Bash – grepping with “shopt -s globstar extglob”

bashwildcards

I have shopt -s globstar extglob in my ./bashrc. I'm searching for files that refer to string Foo in the following command:

grep -Fwn Foo /**/src/**/*.@(h|cpp)

Now I want to except all refers from files Foo.h and Foo.cpp. The following is the command that gain this goal

grep -Fwn Foo /**/src/**/*.@(h|cpp) | grep -v Foo.h | grep -v Foo.cpp

I'd like to make it without piping command using ! and & in location pattern. I mean something like the following

grep -Fwn Foo /**/src/**/@(*.@(h|cpp)&(!(Foo.*)))

Why the command from above do not work and how to fix it?

Best Answer

Simply because there's no such thing as a &(...) operator in bash. bash only implements a subset of ksh patterns with extglob. Here you want:

grep -Fwn Foo /**/src/**/!(Foo).@(h|cpp)

With ksh93, you can use & this way:

grep -Fwn Foo /**/src/@(*.@(h|cpp)&!(Foo*))

zsh has a and-not operator with extendedglob:

grep -Fwn Foo /**/src/(*.(h|cpp)~Foo*)
Related Question