使用 zsh globbing 进行 grepping 时排除目录

Exclude directory when grepping with zsh globbing

我有一些文件结构,其中包含具有不同深度的构建文件夹的项目。我正在尝试使用 zsh(扩展)通配来排除构建文件夹中的文件。

我尝试使用以下命令和许多其他变体:

grep "string" (^build/)#

我读这个是 "Any folder that doesn't match build 0 or more times."

但是我仍然从以下文件夹中获取结果:

./ProjectA/build/.../file.mi

./ProjectB/package/build/.../file2.mi

有什么建议吗?

我认为您不需要让 shell 参与该任务; grep 有它自己的 file-globber。来自 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.

所以像这样的事情应该可以为您完成工作:

grep -R "string" --exclude-dir='build'

该过滤器将忽略名为 "build" 的子目录;如果你想过滤掉 包含 字符串 "build" 的目录(例如 "build2" 或 "test-build")然后在排除模式中使用 globbing:

grep -R "string" --exclude-dir='*build*'

为了完整起见,我还在此处介绍了如何使用我或多或少熟悉的两个流行 grep 替代方案来做同样的事情:

使用 glob 限定符 e 对我有用,'grep' 和 'ls':

grep -s "string" **/*(e[' [[ ! `echo "$REPLY" | grep "build/" ` ]]'])

这应该有效:

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

解释:

  • ^build: 任何未命名的东西 build
  • ^build/: 任何 目录 未命名的构建。它不会匹配任何其他文件类型
  • (^build/)#:由未命名的元素组成的任何目录路径 build。同样,这将不匹配最后一个元素不是目录的路径
  • (^build/)#*:除了最后一个元素之外的所有路径都不得命名为 build。这也将列出文件。它还假设如果文件本身被命名为 build 就没问题。如果不是这种情况,您必须使用 (^build/)#^build
  • (^build/)#*(.):与之前相同,但仅限于通过 glob 限定符匹配普通文件 (.)