Zack
Zack

Reputation: 677

Exclude directory when grepping with zsh globbing

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

Answers (3)

Adaephon
Adaephon

Reputation: 18349

This should work:

grep string (^build/)#*(.)

Explanation:

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

ma-ti
ma-ti

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

asamarin
asamarin

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:

Upvotes: 0

Related Questions