比较两个文件时,grep 导致整个系统冻结

con*_*tti 1 memory linux freeze grep arch-linux

我想是比较两个文件,并检查每一行的file1存在file2。我的第一次尝试:grep -v -f file2 file1。这导致了很多语法错误(但没有冻结任何东西)。我很快发现这是因为我需要-F按照此处的说明使用。所以我跑了grep -Fvf file2 file2,几秒钟后我的整个系统被冻结了几分钟,直到 xorg 完全崩溃。

我能够拍下这张冻结屏幕的照片: 资源管理器

当我终于能够进入 tty2 时,我收到了这样的问候: 错误

问题:

  1. 系统冻结的原因仅仅是内存不足,还是更多?
  2. 为什么 grep 使用 ~14GB RAM(并且想要更多)来比较两个 250MB 的文件?
  3. 我可以使用工具来限制 grep 可以使用的 RAM,但是 AFAIK 一旦达到 x GB 的 RAM,所有这些都会简单地终止进程,所以这对我没有帮助。在这种情况下怎么办?假设我们必须使用 grep。

编辑:我已经找到了没有 grep 的解决方法。我真的很好奇为什么以及如何发生这种情况。两个 250MB 文件的 +14GB RAM 对我来说似乎很奇怪。我不是在寻找关于如何将我的文件与这个问题进行比较的替代方法。

dir*_*rkt 6

  1. 原因肯定是内存不足。

  2. 因为您不是“比较两个文件”,所以您使用一个 250MB 的文件作为grep的模式源。Grep 将这些模式编译成一个确定性有限自动机的变体,并且这个 DFA 的表示会占用内存。如果您有很多模式(例如 250MB 的模式),它会占用大量空间,因为将对应于许多模式的非确定性有限自动机转换为 DFA 会导致指数膨胀。

grep可以非常有效地查找一个或多个大文件中的几个模式。它不是用来“比较”文件的。如果你尝试使用它,事情可能会出错。正如他们在你的情况下所做的那样。

复杂性很重要,这就是为什么你要学习 O 符号和所有这些花哨的东西。

  1. 在这种情况下,您使用的是适合您的情况的程序,而不是使用针对您的问题类型的空间指数算法的程序。

你说你不想知道替代方案,但由于它涉及一个鲜为人知的工具,我无论如何都会告诉你:

如果问题是“文件 1 的每一行是否也存在于文件 2 中,无论顺序如何”,那么您要做的是对两个文件进行排序,然后使用comm,它需要已排序的文件,并在文件 1 中输出 (1) 行,但是不在 file2 中,在 file2 中的 (2) 行,但在您方便时不在 file1 和 (3) 行中的两个文件中。