我尝试使用grep
来查找单词world
,同时排除mail
、tmp
或 的任何目录.cpanel
。我可以使用 来单独忽略它们--exclude-dir=name
,但从阅读其他线程来看,似乎我应该能够使用逗号分隔的列表。但是,我尝试以下方法却没有成功:
grep 'world' --exclude-dir={./mail,./.cpanel,./tmp} -ri .
和
grep 'world' --exclude-dir={mail,.cpanel,tmp} -ri .
因为两者都不起作用。--exclude-dir
仅使用一个目录即可,如下所示:
grep 'world' --exclude-dir=mail -ri .
但我收到了tmp
可以.cpanel
列表。
我如何在一个命令中指定所有目录(一旦我得到.cpanel
并tmp
排除,我怀疑可能还有一些不相关的目录,所以我不想--exclude-dir
每个目录都有一个)。
答案1
exclude-dir
取决于grep
版本
该标志的引入是通过 > 引入的2.5.2:
+版本 2.5.2 + - 新选项--exclude-dir允许指定目录模式 + 将从递归 grep 中排除。
(H/T 至Johnsyweb 在 SO 上关于追踪版本的回答)
在实施时,它以常规的、以逗号分隔的要排除的目录列表的形式工作,没有空格:
$ grep 'foo' -ri .
./a/test.txt:foo bar baz
./c/test.txt:foo bar baz
./b/test.txt:foo bar baz
$ grep 'foo' --exclude-dir={a,b} -ri .
./c/test.txt:foo bar baz
或者,如果你的版本grep
不支持{}
,并且你不想继续输入目录
将目录放在一个数组中,然后将其扩展为命令:
$ exclude=( "mail" ".cpanel" "tmp" )
$ for dir in ${exclude[@]}; do echo "--exclude-dir=$dir"; done
--exclude-dir=mail
--exclude-dir=.cpanel
--exclude-dir=tmp
使用方法如下:
$ grep 'world' $(for dir in ${exclude[@]}; do echo "--exclude-dir=$dir"; done) -ri .
解释:替换$()
将把你的--exclude-dir
s 作为参数传递给 grep grep
。
答案2
以下可能是也可能不是正确的答案,这取决于您对命令的定义:
grep -iR 'world' . | grep -v mail | grep -v ".cpanel" | grep -v tmp
(实际上,我很确定“.cpanel”不需要引号。但我倾向于谨慎行事,因此,如果有任何标点符号,我倾向于引用它,而不是试图记住所有的细微差别。)
如果您对“命令”的定义是指定可执行文件时,那么这就是四个命令,无法回答问题。但是,如果您对“命令”的定义是基于您按下“enter”键时,或者您说有 5 个命令(一个命令包含 4 个其他命令),那么我已经成功提供了一个可以执行您要求的命令。(此外,这种方法不依赖于名为 --exclude-dir 的 GNU 扩展,而是适用于更多操作系统。)