2016-08-02 3 views
-1

매우 커지고 끊임없이 변화하는 파일 (일반적으로 약 1.5M 라인)을 반복하고 각 라인에서 연산을 수행하려고합니다. 로그 파일이기 때문에 파일 끝에 새 줄이 추가됩니다. 내 프로그램은 사용자가 각 줄이 일치해야하는 매개 변수를 지정하고 가장 최근의 일치 항목을 반환 할 수있게합니다. 결과적으로, 파일의 끝에서 시작하여 프로그램을 효율적으로 만들기 위해 노력하고 싶습니다. (선 목록을 만들고 역순으로 만드는 대신) 사용자가 "사과"나는 "2016년 1월 4일 0시 사과"를 반환하는 선에서 가장 가까운 싶습니다 일치하는 1 개 라인을 요청하는 경우대용량 파일을 반복하는 효율적인 방법

2016-01-01 01:00 apple 

2016-01-02 05:00 banana 

2016-01-03 03:00 apple 

2016-01-04 00:00 apple 

2016-01-05 12:00 banana 

: 여기

는 예를 들어 상황입니다 파일 끝까지. 단 5 개의 라인 만 있으면 이것은 어렵지 않지만 수백만이되면 성능이 저하됩니다. 나는 파일의 끝에 시작하기 위해 tail -n [file size]을 사용해 보았지만,이 방법은 잘 확장되지 않는다. 성능을 향상시키기 위해 반복을 사용할 수 없습니다 (결과가 파일의 마지막 줄인 경우 1,500,000 줄까지 반복하고 싶지 않습니다).

나는 "덩어리"로 파일을 깨는 시도했습니다 또 다른 방법 :

| 
| Remaining lines 
| 

... 

| 
| Second group of n lines 
| 

| 
| First group of n lines 
| 

나는 다음 각 청크 만 선을 스트리밍 할 GNU sed을 사용합니다. 그러나 프로그램의 성능이 거의 향상되지 않았 음을 발견했습니다 (실제로는 n이 작을 때 고통을 겪었습니다).

파일을 반복하는 동안 런타임을 최소화하면서이 작업을 수행하는 더 좋은 방법이 있습니까? 나는 ("하위 프로세스"를 통해) 리눅스 커맨드 라인에서 다른 프로그램을 사용해 왔지만 파이썬에 내장 된 것을 사용하는 것이 좋을지도 모른다. 나는 올바른 방향으로 나를 이끌어 줄 정보를 매우 감사 할 것입니다.

파이썬 2.7.3, 2.7.10, 2.7.11-c7, 3.3.6 및 3.5.1에 ​​대한 액세스 권한이있는 Linux를 사용하고 있습니다.

+0

이 질문은 많이 묻습니다. _a lot_. 아직 봤어? –

+5

가능한 dublicate : http : // stackoverflow.com/questions/3346430/가장 효율적인 방식으로 처음부터 끝까지 텍스트 파일을 완성 –

+0

예, 물론입니다. 문제는 보려는 줄 수를 제한하는 것입니다. 즉 사용자가 5 개의 결과를 원하고 처음 10 개의 줄을 찾은 경우 나머지 파일을 읽지 않으려 고하고 파일을 역방향으로 작업하는 경우입니다. 단순히 파일을 반복하는 것입니다 ('for line in reversed (open (file) .readlines())) 최선의 선택은 무엇입니까? – robben

답변

0

파일을 연 후 파일 핸들의 seek(bytes, start_point) 메서드를 사용하여 파일의 임의의 위치 (바이트 수)로 건너 뛸 수 있습니다. 예 :

with open(my_file) as f: 
    f.seek(1024, 0) 
    for line in f: 
     print(line) 

이렇게하면 첫 번째 킬로 바이트를 제외한 파일의 모든 줄이 인쇄됩니다. 음수를 입력하면 역방향으로 이동하고 두 번째 인수에 2 값을 제공하면 파일 끝에서부터 계산됩니다. 따라서 f.seek(-1024, 2)을 호출하면 파일의 마지막 킬로바이트 만 인쇄됩니다.

파일이 청크 크기보다 작을 때 죽지 않도록 보안 대책이 필요할 수도 있습니다.하지만 그렇게 할 수 있습니다. (당신이 다시 더 갈 필요가 밝혀 경우에, 그 또한 아주 사소한 : 단순히 다시 seek를 호출합니다.)

+2

하지만,이 경고 (https://docs.python.org/3/tutorial/inputoutput.html#methods-of-file-objects) : "텍스트 파일 (mode 문자열), 파일의 시작 부분에 상대적인 탐색 만 허용된다 (예외는'seek (0, 2)'로 파일 끝을 찾는다). 유효한 오프셋 값은'f.tell()'또는 0입니다. 다른 오프셋 값은 정의되지 않은 동작을 생성합니다. " –

+0

아마도'tell '과'seek'가 바이트 오프셋을 사용하기 때문일 것입니다. 임의의 값을 전달하면 멀티 바이트 문자가 중간에 오게됩니다. 아주 좋은 점은, 특히이 버그는 찾기가 어렵 기 때문입니다. – spectras

0

당신은 사용할 수 있습니다 : 파이썬 3

for line in reversed(open("filename").readlines()): 
    print line.rstrip() 

을 그리고 :

for line in reversed(list(open("filename"))): 
    print(line.rstrip()) 

이것은 이미 여기에 답변되었습니다 : Read a file in reverse order using python

+0

대용량 파일의 경우 매우 느립니다. –

관련 문제