Ricerca binaria in un file di testo ordinato


13

Ho un grosso file ordinato con miliardi di righe di lunghezza variabile. Data una nuova riga, vorrei sapere quale numero di byte otterrebbe se fosse stato incluso nel file ordinato.

Esempio

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

Dato l'ingresso 'pippo' otterrei l'output 9.

Questo è facile da fare semplicemente esaminando l'intero file, ma essendo miliardi di righe di lunghezza variabile sarebbe più veloce fare una ricerca binaria.

Esiste già un tale strumento di elaborazione del testo?

Modificare:

Ora funziona: https://gitlab.com/ole.tange/tangetools/blob/master/bsearch/bsearch


quanto dura la linea che stai cercando (in caratteri)? e quante righe devi cercare?
gogoud,

@gogoud Non sto cercando uno strumento limitato, ma uno che funzioni su qualsiasi file di testo (indipendentemente dalla lunghezza o dal numero di righe).
Ole Tange,

per coloro che potrebbero voler generare un input così gigantesco: unix.stackexchange.com/a/279098/9689
Grzegorz Wierzowiecki,

Risposte:


4

Non sono a conoscenza di alcuni strumenti standard che lo fanno. Tuttavia puoi scrivere il tuo. Ad esempio il seguente script ruby ​​dovrebbe fare il lavoro.

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

È un po 'complicato perché dopo la ricerca di solito sei nel mezzo di una riga e quindi devi fare una readline per arrivare all'inizio della riga successiva, che puoi leggere e confrontare con la tua chiave.


Può essere modificato per accettare -n / -r per elaborare i file ordinati per sort -re sort -n?
Ole Tange,

Il codice sopra è principalmente per mostrare l'idea. È tutt'altro che perfetto. (Ad esempio non riesce se la chiave va al primo posto.) Sentiti libero di adattarti alle tue esigenze.
michas,

5

(Questa non è una risposta corretta alla tua domanda, solo un punto di partenza.)

Ho usato sgrep (grep ordinato) in una situazione simile.

Sfortunatamente (abbiamo bisogno dello stato corrente) non ha un output con offset di byte; ma penso che potrebbe essere facilmente aggiunto.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.