2010-12-17 31 views
6

Giả sử tôi có ổ cứng HDD Ubuntu 10GB ở Hoa Kỳ (và tôi sống ở một nơi khác) và tôi có tệp văn bản 9 GB trên ổ cứng . Tôi có 512MB RAM, và khoảng cùng một lượng trao đổi. Với một thực tế là tôi không thể thêm nhiều không gian HDD và không thể di chuyển tệp đến một nơi khác để xử lý, có phương pháp hiệu quả để xóa một số dòng khỏi tệp bằng Python hay không. ?Làm cách nào để xóa các dòng khỏi một tệp lớn bằng Python, trong môi trường giới hạn

Trả lời

3

Làm thế nào về điều này? Nó chỉnh sửa các tập tin tại chỗ. Tôi đã thử nghiệm nó trên một số tập tin văn bản nhỏ (trong Python 2.6.1), nhưng tôi không chắc chắn như thế nào nó sẽ thực hiện trên các tập tin lớn vì tất cả các nhảy xung quanh, nhưng vẫn ...

I ' đã sử dụng một vòng lặp không xác định trong khi kiểm tra EOF bằng tay, vì for line in f: không hoạt động chính xác (có lẽ tất cả các bước nhảy lộn xộn xung quanh sự lặp lại bình thường). Có thể có cách tốt hơn để kiểm tra điều này, nhưng tôi tương đối mới với Python, vì vậy ai đó vui lòng cho tôi biết nếu có.

Ngoài ra, bạn cần xác định hàm isRequired(line).

writeLoc = 0 
readLoc = 0 
with open("filename" , "r+") as f: 
    while True: 
     line = f.readline() 

     #manual EOF check; not sure of the correct 
     #Python way to do this manually... 
     if line == "": 
      break 

     #save how far we've read 
     readLoc = f.tell() 

     #if we need this line write it and 
     #update the write location 
     if isRequired(line): 
      f.seek(writeLoc) 
      f.write(line) 
      writeLoc = f.tell() 
      f.seek(readLoc) 

    #finally, chop off the rest of file that's no longer needed 
    f.truncate(writeLoc) 
+0

+1: Hầu như chính xác giải pháp của tôi, nhưng với tất cả các chi tiết không rõ ràng được điền vào. Và được kiểm tra. –

+1

Giải pháp tuyệt vời. –

+0

Cảm ơn bạn đã gợi ý, tôi hơi lo lắng rằng nếu có điều gì xảy ra trong quá trình này, tệp của tôi sẽ không ở trạng thái ban đầu? Do thực tế là số dòng thực sự quan trọng trong hàm isRequired (line). Tôi nhận thức được rằng tôi có thể đăng nhập/ghi vào một tập tin để "nhớ" những gì đã được thay đổi và tiếp tục sau đó, nhưng tôi muốn xem nếu có một cách ít nỗ lực để đạt được điều này. –

0

Chỉ đọc tuần tự và ghi vào tệp.

f.readlines() trả về danh sách chứa tất cả các dòng dữ liệu trong tệp. Nếu được cung cấp một kích thước tham số tùy chọn , nó đọc nhiều số byte từ tệp và đủ hơn để hoàn thành một dòng và trả về các dòng từ đó. Điều này thường được sử dụng để cho phép đọc hiệu quả tệp lớn theo số dòng, nhưng không phải tải toàn bộ tệp toàn bộ tệp trong bộ nhớ. Chỉ hoàn thành dòng mới sẽ được trả lại.

Source

+0

Viết tới đâu? Không có đủ không gian. – khachik

+0

Nó phụ thuộc vào kiến ​​trúc/hệ thống tập tin tôi đoán ... nhưng tôi muốn nói rằng bạn không thể sửa đổi một tập tin theo nghĩa đó, bạn cần viết lại nó. – phant0m

0

Process file nhận được 10/20 trở lên MB bộ khối. Đây sẽ là cách nhanh nhất.

Cách khác để làm điều này là phát trực tuyến tệp này và lọc tệp bằng AWK chẳng hạn.

dụ mã giả:

file = open(rw) 
linesCnt=50 
newReadOffset=0 
tmpWrtOffset=0 
rule=1 
processFile() 
{ 
    while(rule) 
    { 
     (lines,newoffset)=getLines(file, newReadOffset) 
     if lines: 
      [x for line in lines if line==cool: line] 
      tmpWrtOffset = writeBackToFile(file, x, tmpWrtOffset) #should return new offset to write for the next time 
     else: 
      rule=0 
    } 
} 

Để thay đổi kích thước tập tin tại việc sử dụng cuối truncate(size=None)

+0

'-1 hater' hãy giải thích tại sao bạn nghĩ rằng nó là crap? – bua

+4

Tại sao bạn sẽ viết mã giả cho Python? Đối với vấn đề đó, tại sao bạn sẽ viết mã giả có vẻ thấp hơn so với Python thường không? –

+0

Bởi vì tôi không có khả năng để kiểm tra là nó chạy và tôi không phải là lập trình viên python bản địa. Điều này chỉ cần đưa ra một ý tưởng những gì ông cần phải nhận thức được. Mã cuối cùng sẽ trông như thế nào chứ không phải vấn đề của tôi .... – bua

2

Hãy thử điều này:

currentReadPos = 0 
removedLinesLength = 0 
for line in file: 
    currentReadPos = file.tell() 
    if remove(line): 
     removedLinesLength += len(line) 
    else: 
     file.seek(file.tell() - removedLinesLength) 
     file.write(line + "\n") 
     file.flush() 
    file.seek(currentReadPos) 

tôi đã không chạy này, nhưng ý tưởng là để thay đổi tệp bằng cách ghi đè các dòng bạn muốn xóa bằng các dòng bạn muốn giữ lại. Tôi không chắc chắn cách tìm kiếm và sửa đổi tương tác với việc lặp qua tệp.

+0

+1 để cung cấp thông tin có liên quan/hữu ích –

1

Cập nhật:

Tôi đã thử fileinput với inplace bằng cách tạo ra một tập tin 1GB. Những gì tôi mong đợi khác với những gì đã xảy ra. Tôi đọc tài liệu đúng lúc này.

Tùy chọn lọc inplace: nếu đối số inplace keyword = 1 được truyền để fileinput.input() hoặc đến FileInput constructor, các tập tin là chuyển đến một tập tin sao lưu và chuẩn đầu ra là hướng đến tệp đầu vào (nếu tệp có cùng tên với tệp sao lưu đã tồn tại, nó sẽ được thay thế một cách im lặng) .

từ docs/fileinput

Vì vậy, điều này dường như không là một lựa chọn ngay bây giờ cho bạn. Vui lòng kiểm tra các câu trả lời khác.


Trước Edit:

Nếu bạn đang tìm kiếm để chỉnh sửa các tập tin inplace, sau đó kiểm tra fileinput mô-đun Python - Docs.

Tôi thực sự không chắc chắn về hiệu quả của nó khi được sử dụng với tệp 10gb. Nhưng, với tôi, điều này dường như là lựa chọn duy nhất bạn có sử dụng Python.

+0

Cảm ơn, +1 để cung cấp câu trả lời có liên quan. –

Các vấn đề liên quan