-not -name 不适用于 find

amp*_*ent 7 find

我正在尝试使用 find/grep 在我的代码库中查找一些文本模式。我想排除我的构建过程将源文件复制到的非源目录:

find . -name *.java -not -name *target* -exec grep -l 'someText' {} \; 2>/dev/null
Run Code Online (Sandbox Code Playgroud)

不幸的是,我仍然在结果中得到目标目录,例如:

./toplevel/src/com/domain/toplevel/module/SourceFile.java
Run Code Online (Sandbox Code Playgroud)

我做错了什么,我该如何解决?

Sté*_*las 8

-name pattern匹配文件名。SourceFile.java不匹配*pattern*,因此包含在内。如果您不想进入名称包含 的目录target,那么您需要:

find . -name '*target*' -prune -o -name '*.java' \
  -exec grep -sl 'someText' {} +
Run Code Online (Sandbox Code Playgroud)

(记住引用模式,否则它们可以被 shell 扩展)。

对于几种模式:

find . \( -name 'pattern1' -o -name 'pattern2' \) -prune \
  -o -name '*.java' -exec grep -sl 'someText' {} +
Run Code Online (Sandbox Code Playgroud)

-a当两个谓词之间没有指定时,AND ( ) 是隐含的。AND优先于OR( -o),因此是上面的括号)。

请注意,这!-not.

如果你想匹配完整路径,那么你需要使用-path

find . -name '*.java' ! -path '*target*' -exec grep -sl someText {} +
Run Code Online (Sandbox Code Playgroud)

但这并没有停止find进入*target*目录,这有点浪费,因为find不会报告那里的任何文件。