grep在大文件上表现不佳,还有其他选择吗?

时间:2014-11-05 20:18:53

标签: perl awk sed grep

我有一个差异,它基本上等同于额外的唯一行或在文件中移动的行,因此它们的行号已经改变。为了确定什么是真正的新增加,我运行这个小的perl片段将“已解析”的行与“未解析的”行分开:

perl -n -e'
    /^\-([^\-].*?)\([^,\(]+,\d+,\d+\).*$/ && do { print STDOUT "$1\n"; next; };
    /^\+([^\+].*?)\([^,\(]+,\d+,\d+\).*$/ && do { print STDERR "$1\n"; next; };
' "$delta" 1>resolved 2>unresolved

实际上这很快就完成了工作,将6000多行差异分成两个3000+行文件,删除了对行号和统一差异装饰的任何引用。接下来是grep命令,似乎在100%CPU上运行了近9分钟(真实):

grep -v -f resolved unresolved

这实际上是从未解析的文件中删除所有已解析的行。 9分钟后,输出恰好是9行输出 - 独特的添加或未解析的行。

首先,当我过去使用grep时,它已经相当不错了,那么为什么在这种情况下它会非常慢并且CPU很饿?

其次,是否有更有效的替代方法从一个文件中删除包含在另一个文件中的行?

2 个答案:

答案 0 :(得分:8)

如果要在两个文件中匹配的行应该是完全匹配,则可以使用sort和uniq来完成这项工作:

cat resolved resolved unresolved | sort | uniq -u

上面管道中唯一的非重复行是 unresolved 中不在已解析中的行。请注意,在cat命令中指定已解决两次非常重要:否则uniq也会选择该文件唯一的行。这假定已解决未解决没有重复的行开头。但这很容易处理:只需先排序并将它们统一起来

sort resolved | uniq > resolved.uniq
sort unresolved | uniq > unresolved.uniq

另外,如果我试图匹配固定字符串,我发现fgrep要快得多,所以这可能是另一种选择。

答案 1 :(得分:5)

Grep可能完全解析该文件,因为它已被告知要查找的每一场比赛。你可以尝试" fgrep"如果它存在于你的系统上,或grep -F,如果它不存在,这迫使grep使用Aho-Corasick字符串匹配算法(http://en.wikipedia.org/wiki/Aho%E2%80%93Corasick_string_matching_algorithm),它试图同时匹配所有字符串,只需要一个文件的贯穿。

相关问题