在已排序的文本文件中进行二进制搜索


13

我有一个很大的排序文件,其中包含数十亿行可变长度的行。给定新行,我想知道如果已包含在已排序文件中,它将获得哪个字节数。

a\n
c\n
d\n
f\n
g\n

给定输入“ foo”,我将得到输出9。

仅通过遍历整个文件就很容易做到这一点,但是由于数十亿行可变长度,执行二进制搜索会更快。

这样的文本处理工具已经存在了吗?

编辑:

现在可以了:https : //gitlab.com/ole.tange/tangetools/blob/master/bsearch/bsearch


您要搜索的行多长时间(以字符为单位)?您需要搜索多少行?
gogoud 2015年

@gogoud我不是在寻找一种有限的工具,而是一种适用于任何文本文件的工具(无论行长或行数)。
Ole Tange

对于那些可能希望产生如此巨大输入的人:unix.stackexchange.com/a/279098/9689
Grzegorz Wierzowiecki

Answers:


4

我不知道执行此操作的某些标准工具。但是,您可以编写自己的。例如,下面的ruby脚本就可以完成这项工作。

file, key = ARGV.shift, ARGV.shift
min, max = 0, File.size(file)

File.open(file) do |f|
  while max-min>1 do
    middle = (max+min)/2
    f.seek middle
    f.readline
    if f.eof? or f.readline>=key
      max = middle
    else
      min = middle
    end
  end
  f.seek max
  f.readline
  p f.pos+1
end

这有点棘手,因为在搜索之后,您通常位于某一行的中间,因此需要执行一个readline才能到达下一行的开始,您可以读取该行并将其与您的密钥进行比较。


可以将其更改为接受-n / -r来处理按sort -r和排序的文件sort -n吗?
Ole Tange 2015年

上面的代码主要是为了展示这个想法。这远非完美。(例如,如果将密钥放在首位,它将失败。)请随意适应您的需求。
michas,2015年

5

(这不是对您问题的正确答案,只是一个起点。)

我在类似情况下使用了sgrep(排序的grep)。

不幸的是(我们需要当前状态)它没有字节偏移输出。但我认为可以轻松添加。


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.