Binäre Suche in einer sortierten Textdatei

13

Ich habe eine große sortierte Datei mit Milliarden Zeilen variabler Länge. Angesichts einer neuen Zeile möchte ich wissen, welche Bytenummer sie erhalten würde, wenn sie in die sortierte Datei aufgenommen worden wäre.

Beispiel

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

Bei der Eingabe 'foo' würde ich die Ausgabe 9 erhalten.

Dies ist einfach zu bewerkstelligen, indem einfach die gesamte Datei durchgegangen wird. Da es sich jedoch um Milliarden von Zeilen mit variabler Länge handelt, wäre eine binäre Suche schneller durchzuführen.

Existiert ein solches Textverarbeitungswerkzeug bereits?

Bearbeiten:

Es funktioniert jetzt: https://gitlab.com/ole.tange/tangetools/blob/master/bsearch/bsearch

Ole Tange
quelle
Wie lang ist die gesuchte Zeile (in Zeichen)? und nach wie vielen solchen Zeilen müssen Sie suchen?
Gogoud
@gogoud Ich bin nicht auf der Suche nach einem eingeschränkten Tool, sondern nach einem Tool, das mit jeder Textdatei (unabhängig von der Zeilenlänge oder der Anzahl der Zeilen) funktioniert.
Ole Tange
Für diejenigen, die solch einen gigantischen Input generieren möchten
Grzegorz Wierzowiecki

Antworten:

4

Mir ist kein Standardwerkzeug bekannt, das dies tut. Sie können jedoch Ihre eigenen schreiben. Zum Beispiel sollte das folgende Ruby-Skript den Job erledigen.

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

Es ist etwas knifflig, da Sie sich nach der Suche normalerweise in der Mitte einer Zeile befinden und daher eine Lesezeile ausführen müssen, um zum Anfang der folgenden Zeile zu gelangen, die Sie lesen und mit Ihrem Schlüssel vergleichen können.

michas
quelle
Kann es geändert werden, um -n / -r zu akzeptieren, um Dateien zu verarbeiten, die nach sort -rund sortiert sind sort -n?
Ole Tange
Der obige Code dient hauptsächlich der Veranschaulichung der Idee. Es ist alles andere als perfekt. (Zum Beispiel schlägt es fehl, wenn der Schlüssel an erster Stelle steht.) Sie können sich jederzeit an Ihre Bedürfnisse anpassen.
Michas
5

(Dies ist keine korrekte Antwort auf Ihre Frage, sondern nur ein Ausgangspunkt.)

Ich habe sgrep (sortiert grep) in einer ähnlichen Situation verwendet.

Leider (wir brauchen den aktuellen Stand) hat es keine byte-versetzte Ausgabe; aber ich denke, es könnte leicht hinzugefügt werden.

Joao
quelle