Reputation: 677
I have some file structure which contains projects with build folders at various depths. I'm trying to use zsh (extended) globbing to exclude files in build folders.
I tried using the following command and many other variants:
grep "string" (^build/)#
I'm reading this as "Any folder that doesn't match build
0 or more times."
However I'm still getting results from folders such as:
./ProjectA/build/.../file.mi
./ProjectB/package/build/.../file2.mi
Any suggestions?
Upvotes: 0
Views: 2746
Reputation: 18349
This should work:
grep string (^build/)#*(.)
^build
: anything not named build
^build/
: any directory not named build. It will not match any other file type(^build/)#
: any directory path consisting out of elements that are not named build
. Again, this will not match a path where the last element is not a directory(^build/)#*
: Any path where all but the last element must not be named build
. This will also list files. It also assumes that it would be ok, if the file itself were named build
. If that is not the case you have to use (^build/)#^build
(^build/)#*(.)
: Same as before, but restricted to only match normal files by the glob qualifier (.)
Upvotes: 5
Reputation: 134
Using the glob qualifier e
did the trick for me, both for 'grep' and 'ls':
grep -s "string" **/*(e[' [[ ! `echo "$REPLY" | grep "build/" ` ]]'])
Upvotes: 0
Reputation: 1594
I think you don't need to involve the shell for that task; grep
comes with its own file-globber. From manpage:
--exclude-dir=GLOB
Skip any command-line directory with a name suffix that matches the pattern GLOB. When searching recursively, skip any subdirectory whose
base name matches GLOB. Ignore any redundant trailing slashes in GLOB.
So something like this should get the job done for you:
grep -R "string" --exclude-dir='build'
That filter will leave out subdirectories called exactly "build"; if you want to filter out directories that contain the string "build" (such as "build2" or "test-build") then use globbing inside the exclusion pattern:
grep -R "string" --exclude-dir='*build*'
For completeness' sake, I also include here how to do the same thing with two popular grep
alternatives that I'm more or less familiar with:
ag -G '^((?!build).)*$' string
rg -g '!build'
Upvotes: 0