如何在整个文件系统中搜索文本?

Lev*_*der 65 grep recursive

假设应该使用 grep 工具,我想在整个文件系统中搜索文本字符串“800x600”。

我试过:

grep -r 800x600 /
Run Code Online (Sandbox Code Playgroud)

但它不起作用。

我相信我的命令应该做的是递归地遍历 root 下的所有文件/文件夹以获取文本“800x600”并列出搜索结果。

我究竟做错了什么?

Ric*_*ner 84

我通常使用这种风格的命令来运行grep多个文件:

find / -xdev -type f -print0 | xargs -0 grep -H "800x600"
Run Code Online (Sandbox Code Playgroud)

这实际上是为系统上的每个文件创建一个列表,然后对于每个文件,grep使用给定的参数和每个文件的名称执行。

-xdev参数告诉 find 它必须忽略其他文件系统 - 这有利于避免特殊文件系统,例如/proc. 然而,它也会忽略普通的文件系统——例如,如果你的 /home 文件夹在不同的分区上,它不会被搜索——你需要说find / /home -xdev ....

-type f意味着只搜索文件,所以目录、设备和其他特殊文件将被忽略(它仍然会递归到目录中并grep在其中的文件上执行——它只是不会grep在目录本身上执行,这无论如何都不起作用)。以及告诉它始​​终在其输出中打印文件名的-H选项grep

find接受各种选项来过滤文件列表。例如,-name '*.txt'仅处理以 .txt 结尾的文件。-size -2M表示小于 2 兆字节的文件。-mtime -5表示最近五天内修改过的文件。将它们与 -a for-o for or连接在一起,并使用'('括号')'对表达式进行分组(在引号中以防止 shell 解释它们)。例如:

find / -xdev '(' -type f -a -name '*.txt' -a -size -2M -a -mtime -5 ')' -print0 | xargs -0 grep -H "800x600"
Run Code Online (Sandbox Code Playgroud)

查看man find以查看可能的过滤器的完整列表。

  • 不,`find` 命令末尾的`+` 符号实际上与`xargs` 做同样的事情:它产生一个带有多个参数的`grep` 进程。 (3认同)
  • 请注意,`-xdev` 将排除_所有_其他文件系统,而不仅仅是特殊的。(例如,如果你将 `/home` 挂载为一个单独的分区,它就不会被搜索。) (2认同)

Cal*_*leb 17

通常情况下,您不希望实际搜索系统上的所有内容。Linux 对所有内容都使用文件节点,因此某些“文件”不是您想要搜索的内容。例如/dev/sda,您的第一个硬盘驱动器的物理块设备。您可能想要搜索已安装的文件系统而不是原始磁盘设备。此外,/dev/random每次阅读时都会吐出随机数据。搜索没有多大意义。/proc在您的情况下,文件系统也有问题。

我会推荐两件事之一。

  1. 不要在 root 处搜索,只搜索可能有用的地方。搜索/home/usr/etcseparatly。您要查找的信息可能属于特定类型,因此无论如何它都可能位于特定文件夹中。配置设置应该在/etc. 您的个人数据文件应该在/home. 将搜索限制在像这样的主要区域将大大减少递归 grep 的问题。

  2. 排除有问题的区域使用--exclude-dir和一组你知道你不需要这样的东西:
    grep -r --exclude-dir /proc --exclude-dir /dev --exclude-dir /tmp --exclude-dir /lost+found

最后,在执行大型递归 grep 时遇到一些“权限被拒绝”错误并不少见。在正常使用过程中,您的用户可能无法读取某些文件。只要这些只是一些奇怪的文件,而不是诸如硬盘驱动器或整个 proc 文件系统的原始设备之类的东西,就可以忽略这些错误。实际上,您可以通过将所有错误发送到 never never land 来在命令行上执行此操作:

grep -r search_string /path 2> /dev/null
Run Code Online (Sandbox Code Playgroud)

  • `-I` 排除二进制 (3认同)