2013-04-28 11 views
11

Tôi có một tệp trong đó các dòng được phân cách bằng dấu phân tách nói .. Tôi muốn đọc dòng tệp này theo từng dòng, trong đó các dòng phải dựa trên sự hiện diện của . thay vì dòng mới.Đọc một tệp có dấu phân cách được chỉ định cho dòng mới

Một cách là:

f = open('file','r') 
for line in f.read().strip().split('.'): 
    #....do some work 
f.close() 

Nhưng đây không phải là bộ nhớ hiệu quả nếu tập tin của tôi là quá lớn. Thay vì đọc toàn bộ tập tin, tôi muốn đọc từng dòng một.

open hỗ trợ tham số 'dòng mới' nhưng thông số này chỉ mất None, '', '\n', '\r', and '\r\n' làm đầu vào như được đề cập here.

Có cách nào để đọc các dòng tệp hiệu quả nhưng dựa trên dấu phân tách được chỉ định trước không?

Trả lời

17

Bạn có thể sử dụng một máy phát điện:

def myreadlines(f, newline): 
    buf = "" 
    while True: 
    while newline in buf: 
     pos = buf.index(newline) 
     yield buf[:pos] 
     buf = buf[pos + len(newline):] 
    chunk = f.read(4096) 
    if not chunk: 
     yield buf 
     break 
    buf += chunk 

with open('file') as f: 
    for line in myreadlines(f, "."): 
    print line 
+0

Kudos @NPE! Đơn giản và nó hoạt động như một sự quyến rũ. –

+0

Có thể được đơn giản hóa một chút bằng cách thay đổi sự bắt đầu của vòng lặp ngoài thành 'cho đoạn trong lần lặp (functools.partial (f.read, 4096), ''): buf + = chunk' và thêm' if buf: yield buf' sau vòng lặp (không phải bên trong). – Harvey

2

Cách đơn giản nhất sẽ được xử lý trước các tập tin để tạo ra dòng mới nơi bạn muốn.

Dưới đây là một ví dụ sử dụng perl (giả sử bạn muốn chuỗi 'abc' là newline):

perl -pe 's/abc/\n/g' text.txt > processed_text.txt 

Nếu bạn cũng muốn bỏ qua các dòng mới ban đầu, sử dụng sau đây thay vì:

perl -ne 's/\n//; s/abc/\n/g; print' text.txt > processed_text.txt