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

Cra*_*aig 7 perl awk grep sed

我有一个差异,基本上等于额外的唯一线或在文件中移动的线,因此他们的行号已经改变.为了确定什么是真正的新增加,我运行这个小的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
Run Code Online (Sandbox Code Playgroud)

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

grep -v -f resolved unresolved
Run Code Online (Sandbox Code Playgroud)

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

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

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

小智 9

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

cat resolved resolved unresolved | sort | uniq -u
Run Code Online (Sandbox Code Playgroud)

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

sort resolved | uniq > resolved.uniq
sort unresolved | uniq > unresolved.uniq
Run Code Online (Sandbox Code Playgroud)

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

  • 您可以通过执行以下操作来消除两个进程:`sort -u resolved resolved unresolved`.好的解决方案 (2认同)

小智 6

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