我不确定:
grep -r -i 'the brown dog' /*
真的是你的意思 这意味着grep会在所有非隐藏文件和目录中递归/
(但仍在隐藏文件和目录中查找)。
假设您的意思是:
grep -r -i 'the brown dog' /
注意事项:
- 并非所有的
grep
实现都支持-r
。在执行这些操作的行为之间,行为也有所不同:在遍历目录树时,某些行为遵循目录的符号链接(这意味着您可能最终在同一文件中查找了几次,甚至在无限循环中运行),而某些行为则没有。有些会查看设备文件(例如,这需要花费一些时间/dev/zero
)或管道或二进制文件的内部...,有些则不会。
grep
发现文件后立即开始查找文件是非常有效的。但是,尽管它在文件中查找,但不再寻找要搜索的文件(在大多数情况下,它也是如此)
你的:
find / -type f -exec grep -i 'the brown dog' {} \;
(删除了-r
此处没有意义的文件)效率非常低,因为grep
每个文件只运行一个文件。;
仅应用于仅接受一个参数的命令。而且在这里,由于grep
只查找一个文件,因此不会打印文件名,因此您将不知道匹配项在哪里。
您没有在查看设备文件,管道,符号链接...,也没有在关注符号链接,但仍可能在诸如之类的内容内部/proc/mem
。
find / -type f -exec grep -i 'the brown dog' {} +
会好很多,因为grep
将运行尽可能少的命令。除非上一次运行只有一个文件,否则您将获得文件名。为此,最好使用:
find / -type f -exec grep -i 'the brown dog' /dev/null {} +
或使用GNU grep
:
find / -type f -exec grep -Hi 'the brown dog' {} +
请注意,只有找到足够的文件以供其咀嚼grep
之前find
,它才会启动,因此会有一些初始延迟。并且find
将不会继续搜索更多文件,直到先前的文件grep
返回为止。分配和传递大文件列表会产生一些(可能微不足道的)影响,因此,总的来说,它的效率可能会低于grep -r
不遵循符号链接或查看设备内部信息的效率。
使用GNU工具:
find / -type f -print0 | xargs -r0 grep -Hi 'the brown dog'
如上所述,grep
将运行尽可能少的实例,但find
在第一次grep
调用在第一批内部时将继续查找更多文件。不过,这可能是优势,也可能不是优势。例如,将数据存储在旋转硬盘驱动器上,find
以及grep
访问存储在磁盘上不同位置的数据将导致磁盘磁头不断移动,从而减慢磁盘吞吐量。在RAID设置(其中find
,并grep
可以访问不同的磁盘上),或者放在SSD上,可能使一个积极的变化。
在RAID设置中,运行多个并发 grep
调用也可能会有所改善。仍然在具有3个磁盘的RAID1存储上使用GNU工具,
find / -type f -print0 | xargs -r0 -P2 grep -Hi 'the brown dog'
可能会大大提高性能。但是请注意,grep
只有找到足够的文件来填充第一个grep
命令后,才会启动第二个命令。您可以为它添加一个-n
选项xargs
,以使它更快地发生(并且每次grep
调用传递更少的文件)。
还要注意,如果将xargs
输出重定向到除终端设备以外的任何设备,则greps
s将开始缓冲其输出,这意味着这些grep
s 的输出可能会被错误地交错。您必须在它们上使用stdbuf -oL
(如在GNU或FreeBSD上可用)来解决该问题(您可能仍然会遇到很长的行(通常> 4KiB)的问题)或将它们的输出写在单独的文件中并进行连接最后。
在这里,您要查找的字符串是固定的(不是正则表达式),因此使用该-F
选项可能会有所作为(不太可能因为grep
实现已经知道如何对其进行优化)。
可能会有很大不同的另一件事是,如果您处于多字节语言环境,则将语言环境固定为C:
find / -type f -print0 | LC_ALL=C xargs -r0 -P2 grep -Hi 'the brown dog'
为了避免看里面/proc
,/sys
...,使用-xdev
并指定要在搜索的文件系统:
LC_ALL=C find / /home -xdev -type f -exec grep -i 'the brown dog' /dev/null {} +
或修剪要明确排除的路径:
LC_ALL=C find / \( -path /dev -o -path /proc -o -path /sys \) -prune -o \
-type f -exec grep -i 'the brown dog' /dev/null {} +