정렬 된 텍스트 파일에서 이진 검색


13

수십억 줄의 가변 길이를 가진 큰 정렬 파일이 있습니다. 새로운 줄이 주어지면 정렬 된 파일에 포함 된 경우 어떤 바이트 번호를 얻게되는지 알고 싶습니다.

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

입력 'foo'가 주어지면 출력 9를 얻습니다.

전체 파일을 간단히 살펴보면 쉽게 수행 할 수 있지만 수십억 줄의 가변 길이가 있으면 이진 검색을 수행하는 것이 더 빠릅니다.

그러한 텍스트 처리 도구가 이미 존재합니까?

편집하다:

이제는 https://gitlab.com/ole.tange/tangetools/blob/master/bsearch/bsearch


검색하는 줄이 얼마나 깁니다 (문자)? 그리고 몇 줄을 검색해야합니까?
gogoud December

@gogoud 나는 제한된 도구가 아니라 모든 텍스트 파일에서 작동하는 도구를 찾고 있습니다 (줄 길이 또는 줄 수에 관계없이).
Ole Tange

그런 거대한 입력을 생성하고자하는 사람들을 위해 : 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

탐색 후에는 일반적으로 일부 줄의 중간에 있으므로 다음 줄의 시작 부분에 도달하기 위해 하나의 readline을 수행해야하므로 키와 비교할 수 있기 때문에 약간 까다 롭습니다.


/ -r 프로세스 파일에 의해 분류 -n 받아들이는 변경 될 수 sort -rsort -n?
Ole Tange

위의 코드는 주로 아이디어를 보여주기위한 것입니다. 완벽하지 않습니다. (예를 들어 키가 처음에 오면 실패합니다.) 필요에 따라 자유롭게 조정하십시오.
michas

5

(이것은 질문에 대한 정답이 아니라 시작점입니다.)

나는 욕심을 사용 비슷한 상황에서 (정렬 GREP).

불행히도 (현재 상태가 필요합니다) 바이트 오프셋 출력이 없습니다. 하지만 쉽게 추가 할 수 있다고 생각합니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.