Двійковий пошук у відсортованому текстовому файлі


13

У мене великий сортований файл з мільярдами рядків змінної довжини. З огляду на новий рядок, я хотів би знати, яке число байтів воно отримало, якби воно було включене до сортованого файлу.

Приклад

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

З огляду на вхід 'foo', я отримав би результат 9.

Це легко зробити, просто пройшовши весь файл, але, будучи мільярдами рядків змінної довжини, було б швидше виконати двійковий пошук.

Чи існує такий інструмент для обробки тексту?

Редагувати:

Це зараз: https://gitlab.com/ole.tange/tangetools/blob/master/bsearch/bsearch


як довго триває лінія, яку ви шукаєте (у символах)? і скільки таких ліній потрібно шукати?
gogoud

@gogoud Я шукаю не обмежений інструмент, а той, який працює на будь-якому текстовому файлі (незалежно від довжини рядка чи кількості рядків).
Оле Танге

для тих, хто може створити такий гігантський вклад: unix.stackexchange.com/a/279098/9689
Grzegorz Wierzowiecki

Відповіді:


4

Я не знаю, який стандартний інструмент це робить. Однак ви можете написати своє. Наприклад, наступний сценарій рубіну повинен зробити цю роботу.

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

Це трохи хитро, тому що після пошуку ви зазвичай перебуваєте посередині якогось рядка, і тому вам потрібно зробити один читальний рядок, щоб перейти до початку наступного рядка, який ви можете прочитати та порівняти з вашим ключем.


Чи може бути змінено прийняття -n / -r для обробки файлів, відсортованих за sort -rі sort -n?
Оле Танге

Код, наведений вище, головним чином, щоб показати ідею. Це далеко не ідеально. (Наприклад, виходить з ладу, якщо ключ переходить на перше місце.) Не соромтеся адаптуватися до ваших потреб.
michas

5

(Це не правильна відповідь на ваше запитання, а лише відправна точка.)

Я використовував sgrep (сортований grep) у подібній ситуації.

На жаль (нам потрібен поточний стан), він не має вихід байт-зміщення; але я думаю, що це можна легко додати.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.