我有一个 42M 行的文本文件。每行的前九个字符是数字键。仅提取密钥存在于另一个大约 150 万个密钥列表中的行的最有效方法是什么?文件和键列表都已排序。
使用awk
应该足够有效 - 它提供了内置的关联数组,其中键查找时间与键的数量(您的查找表的数量 - 在您的示例中相对较小)成对数比例。
对于您的输入,这将是:
42M * log2(1.5M) -> 42M * 20 key comparisons
Run Code Online (Sandbox Code Playgroud)
(其中 M 表示 10^6)
如果您的 awk 使用哈希表,则每次键查找只会花费恒定的时间。
基于 awk 的高效解决方案示例(使用默认字段分隔符):
$ awk 'ARGIND == 1 { a[$1] = 1; next } a[$1] { print $0 }' keys.dat largefile.dat
Run Code Online (Sandbox Code Playgroud)
由于两个输入都已排序,因此您可以编写一个更高效的脚本(运行时随输入文件大小线性缩放)。但是编程它会花费更多的时间。
或者您可以使用join
which expect 排序的文件作为输入 - 限制是您的密钥需要按字母顺序排序 - 也许您必须调整输出格式。例如:
$ join -j1 keys.dat largefile.dat
Run Code Online (Sandbox Code Playgroud)
使用-t
配置域分隔和-o
调整输出格式。
这应该与输入大小成线性关系。