2010-06-22 4 views
1

나는 약 4MB의 파일을 가지고있다. (나는 큰 파일이라고 불렀다.) ...이 파일은 160000 라인을 가지고있다. 그리고 특정한 포맷으로 ... 그리고 나는 그들을 일정한 간격으로 (등 간격이 아니라)자를 필요가있다. 특정 형식의 끝 부분을 다른 파일에 씁니다.큰 파일을로드하고 작은 파일로 잘라내는 방법은 무엇입니까?

기본적으로 큰 파일의 정보를 여러 개의 작은 파일로 복사하는 것이 좋습니다. 정보를 하나의 파일에 저장 한 후 특정 패턴이 발생한 후에이 파일을 끝내고이 파일을 다른 파일에 쓰려면이 파일을 끝내야합니다 ...

일반적으로 파일 크기가 작 으면 수행 할 수있는 파일인지 알 수 없습니다. 각 줄을 읽는 file.readline() 패턴이 끝나면 끝내는 지 확인한 다음 패턴이 없으면 파일에 쓰십시오. 차 후 내가 느낀 .. 사전에 ..이 큰 파일을

감사를 수행하는 것은

didnt 한 파일 형식을 언급하는 방법 새가 file..so에 있지만 neccesary 의지하지 열려있는 파일 이름을 변경 필요한 경우 언급하십시오 ..

답변

2

라인의 목록으로 메모리에 주장-큰 파일 :

with open('socalledbig.txt', 'rt') as f: 
    lines = f.readlines() 

는 4메가바이트보다 조금 더 소요됩니다 - 작은을 오늘날의 전화의 표준으로, 훨씬 적은 일반 컴퓨터.

그런 다음 작은 파일에 기록하려는 각 행 그룹의 시작과 끝을 결정하는 데 필요한 처리를 수행하십시오 (질문이 텍스트로 겹칠 수 있는지, 따라서 제약 조건이 매우 까다로운 경우 코드가 더 간단 할 수 있지만 실제 퍼포먼스 패널티가없는 제약 조건이있는 사용 사례도 다루게 될 것입니다. , names -

은 (len(lines) 이상으로 innocuosly 수도 합법적으로 쓸 NOT을 첫 번째 줄의 0부터 인덱스), ends을 (쓰기 첫 번째 줄의 0에서 인덱스 포함) 목록에 starts을이 숫자를 넣어 말 (당신이 쓰고 싶은 파일 이름), 모든 목록은 물론 길이가 동일합니다. 마지막으로 다음

:

assert len(starts) == len(ends) == len(names) 

for s, e, n in zip(starts, ends, names): 
    with open(n, 'wt') as f: 
     f.writelines(lines[s:e]) 

... 그리고 당신이해야 할 모든입니다!

편집는 다음 영업 이익이 목록을 갖는 개념으로 혼동하는 것 같다, 그래서 내가 예를 들어주고 해보자 : 'begin'가 (포함)를 포함하는 행에서 시작하는 파일에 기록 각 블록과에 종료 바로 뒤에 오는 첫 번째 줄은 'end' (포함되어 있음)이며, 쓸 파일의 이름은 result0.txt, result1.txt 등이됩니다. "closing ends"의 수가 "opening begins"의 숫자와 다른 경우 오류가 발생합니다. (기억하고 첫 번째 바로 뒤 따르는 "end"는 모든 보류중인 "starts"을 종료합니다); 'begin' 'end'를 모두 포함 할 수있는 행은 없습니다. 조건

매우 임의의 집합, 확실하게, 그러나, 영업 이익은 우리가하지만 가장 격렬하게 추측 할 수 밖에 그래서, 문제의 실제 특성에 대한 어둠 속에서 완전히 우리를 잎 -?)

outfile = 0 
starts = [] 
ends = [] 
names = [] 
for i, line in enumerate(lines): 
    if 'begin' in line: 
    if 'end' in line: 
     raise ValueError('Both begin and end: %r' % line) 
    starts.append(i) 
    names.append('result%d.txt' % outfile) 
    outfile += 1 
    elif 'end' in line: 
    ends.append(i + 1) # remember ends are EXCLUDED, hence the +1 

맞습니다. 길이가 동일한 세 개의 목록에 대한 assert은 제약 조건을 준수하는지 확인합니다. 제약 및 사양으로

그렇게 물론, 변경되는 것입니다 따라 코드 변경이 조각 - 한 그것이 그렇게 중요합니까 정확히 방법 세 동일한 길이의 목록 starts, endsnames 채우기로 최소한 코드의 나머지 부분은 아닙니다.

+0

쓰기 그룹은 중복되지 않지만 한 줄 간격을 두어야 할 수도 있습니다. 위의 코드에서 시작, 끝 및 이름을 더 명확하게 말할 수 있습니까? – kaki

+0

@kaki, 좋아, 나는 맑은 줄 알았지 만, 내가 더 자세히 도울 수 있도록 완전히 모호한 예제를 추가 할 것이다. –

+0

답장을 보내 주신 분 – kaki

0

실제 코드는 작성하지 않지만 의사 코드는이 작업을 수행합니다.

BIGFILE="filename" 
SMALLFILE="smallfile1" 
while(readline(bigfile)) { 
    write(SMALLFILE, line) 
    if(line matches pattern) { 
     SMALLFILE="smallfile++" 
    } 
} 

정말 나쁜 코드이지만 어쩌면 요점을 얻을 수 있습니다. 나는 어쨌든 파일을 읽어야하므로 파일이 얼마나 큰지는 중요하지 않다고 말했다.

1

4MB 파일이 매우 작아서 메모리에 꼭 맞습니다. 가장 빠른 방법은 패턴을 검색하여 각 라인을 반복하여 패턴에 따라 적절한 파일에 선을 씁니다 (작은 파일에 대한 접근 방식).

관련 문제