我最喜欢的 BASH 命令之一是:
find . -name '*.*' -exec grep 'SearchString' {} /dev/null \;
Run Code Online (Sandbox Code Playgroud)
它在当前目录下的所有文件的内容中搜索指定的 SearchString。作为开发人员,这有时会派上用场。
然而,由于我当前的项目和我的代码库的结构,我想通过不搜索包含“.svn”的目录中或下方的任何文件或任何文件来使此 BASH 命令更加高级以“.html”结尾
find 的 MAN 页面让我感到困惑。我尝试使用 -prune,它给了我奇怪的行为。为了仅跳过 .html 页面(开始),我尝试了:
find . -wholename './*.html' -prune -exec grep 'SearchString' {} /dev/null \;
Run Code Online (Sandbox Code Playgroud)
并没有得到我希望的行为。我想我可能错过了 -prune 的重点。你们能帮帮我吗?
谢谢
Pau*_*aul 248
您可以使用 find 的否定 (!) 功能来不匹配具有特定名称的文件:
find . ! -name '*.html' ! -path '*.svn*' -exec grep 'SearchString' {} /dev/null \;
Run Code Online (Sandbox Code Playgroud)
因此,如果名称以 .html 结尾或在路径中的任何位置包含 .svn,它将不匹配,因此不会执行 exec。
l0b*_*0b0 13
我遇到同样的问题很长时间了,有几种解决方案可以适用于不同的情况:
ack-grep是一种“开发人员grep”,默认情况下会跳过版本控制目录和临时文件。该man页面解释了如何仅搜索特定文件类型以及如何定义您自己的.grep's own--exclude和--exclude-diroptions 可以很容易地用于跳过文件globs和单个目录(不幸的是,没有目录的 globbing)。find . \( -type d -name '.svn' -o -type f -name '*.html' \) -prune -o -print0 | xargs -0 grep ... 应该可行,但从长远来看,上述选项可能不那么麻烦。以下find命令会修剪名称包含 的 目录.svn,虽然它不会下降到目录中,但会打印修剪后的路径名......(-name '*.svn'是原因!)..
您可以通过以下方式过滤掉目录名称:grep -d skip它会默默地跳过此类输入“目录名称”。
随着GNU的grep,您可以使用-H来代替/dev/null。作为一个轻微的附带问题:\+可以比 快得多\;,例如。100万单行文件,使用\;它花了4m20s,使用\+只用了1.2秒。
以下方法使用xargs代替-exec,并假定\n您的任何文件名中都没有换行符。此处使用的 ,xargs与 find 的 非常相似\+。
xargs可以通过'\n'使用-d选项更改输入分隔符来传递包含连续空格的文件名。
这不包括名称包含 .svn和仅搜索不以.html.
find . \( -name '*.svn*' -prune -o ! -name '*.html' \) |
xargs -d '\n' grep -Hd skip 'SearchString'
Run Code Online (Sandbox Code Playgroud)
小智 6
通过使用“ -not ”和“ -and ”:
find . -type f \( \
-not -name "${1}" \
-and -not -name "${2}" \
\)
Run Code Online (Sandbox Code Playgroud)
一行:
find . -type f \( -not -name "${1}" -and -not -name "${2}" \)
Run Code Online (Sandbox Code Playgroud)