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


53

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

我试过了:

grep -r 800x600 /

但这不起作用。

我相信我的命令应该做的是递归地遍历根目录下所有文件/文件夹中的文本“ 800x600”,并列出搜索结果。

我究竟做错了什么?


2
而“不起作用”则指的是什么?它不打印任何输出,挂起或打印很多Permission denied错误吗?您是否以root或普通用户身份运行它?
Alex

我得到了一些帮助,首先,我在用户主目录中尝试运行该命令。因此,现在我已经cd /根了。接下来,我尝试了与上述相同的命令,并且出现了很多“权限被拒绝”错误。好吧,所以现在我尝试sudo grep -r 800x600 /,然后得到一个/ proc / sysrq-trigger:输入/输出错误
Level1Coder 2011年

嗯,不知道为什么它不起作用。您可以通过执行来忽略访问错误grep -r 800x600 / 2>/dev/null。您也可以尝试以root用户身份运行它。
Totor 2014年

Answers:


64

我通常使用这种命令样式来运行grep多个文件:

find / -xdev -type f -print0 | xargs -0 grep -H "800x600"

这实际上是制作系统上每个文件的列表,然后针对每个文件,grep使用给定的参数和每个文件的名称执行。

-xdev参数表明发现它必须忽略其他文件系统-这对于避免使用诸如/proc。之类的特殊文件系统很有好处。但是,它也会忽略普通的文件系统-因此,例如,如果/ home文件夹位于其他分区上,则不会搜索该文件系统-您需要说一下find / /home -xdev ...

-type f表示仅搜索文件,因此目录,设备和其他特殊文件将被忽略(它仍将递归到目录中并grep在其中的文件上执行-它将仅grep在目录本身上执行,无论如何将无法运行)。告诉它始​​终在其输出中打印文件名的-H选项grep

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

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

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


2
请注意,这-xdev将排除所有其他文件系统,而不仅仅是特殊的文件系统。(例如,如果您已/home安装为单独的分区,则不会搜索该分区。)
cjm 2011年

我尝试运行每一个,但都返回一个错误find: paths must precede expression: /
Level1Coder 2011年

1
注意:当不需要正则表达式时,“ fgrep”要比“ grep”快得多,如果要搜索大树,这将有很大的不同。
内森·基德

1
您可以xargs通过这样做来避免以更高的效率进行操作find / -xdev -type f -exec grep -H '800x600' +
Totor 2014年

3
不,命令+末尾的符号find实际上与执行以下操作xargs:生成grep带有多个参数的一个进程。
Totor 2014年

14

通常,您实际上并不希望在系统上搜索所有内容。Linux将文件节点用于所有内容,因此某些“文件”不是您要搜索的内容。例如/dev/sda,第一个硬盘驱动器的物理块设备。您可能要搜索已挂载的文件系统,而不是原始磁盘设备。另外,/dev/random每次读取时都会散出随机数据。搜索没有任何意义。该/proc文件系统也是你的情况的问题。

我建议两件事之一。

  1. 不要从根本上搜索,仅搜索可能有用的地方。搜索/home/usr/etcseparatly。您要查找的信息可能是特定类型的,因此总有可能位于特定文件夹中。配置设置应位于中/etc。您的个人数据文件应位于中/home。像这样将搜索范围限制在一个主要区域,将大大减少递归性问题。

  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

3
-I排除二进制文件
Rahul Patil

2

为了简单起见,我建议使用ack-grep。链接显示了很多情况下ack-grep是更好的选择。

要使用的是,安装后:

ack-grep pattern /

感谢您的推荐,但是我运行了它,但并没有真正给我我期望的搜索结果。好像我需要调整许多设置才能得到我想要的。到目前为止,Richard的答案是开箱即用的。将来也会对此进行研究,因为它似乎也很有用。
Level1Coder


0

*然后我得到一个/ proc / sysrq-trigger:输入/输出错误

您的命令正在运行,您正在收到此错误,因为您正在尝试扫描正在运行的进程中的字符串。

我建议用

grep -exclude-dir = {proc,sys}“ 800x600” /


-3

完全正确-

grep -r "800x600" /

-当前命令中的错误是引号“”。始终将字符串参数grep放在引号中。


3
这不是这里的问题。在将这种特殊类型的参数赋予时,您不需要引号grep。试试看,您会看到的。将字符串“ 800x600”放入文件中,然后grep 800x600 file您会看到它正常工作。OP显然还有其他问题。
slm
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.