2012-09-06 9 views
12

Possible Duplicate:
Get last n lines of a file with Python, similar to tail
Read a file in reverse order using pythonअजगर पढ़ने केवल विशाल पाठ के अंत फ़ाइल

मैं आकार में 15GB के बारे में है कि एक फ़ाइल है, यह है कि मैं से उत्पादन का विश्लेषण करने वाला हूँ एक लॉग फ़ाइल है। मैंने लॉगिंग की केवल कुछ पंक्तियों के साथ पहले से ही एक छोटी लेकिन छोटी छोटी फ़ाइल का मूल विश्लेषण किया है। पार्सिंग तार समस्या नहीं है। मुद्दा विशाल फ़ाइल और इसमें अनावश्यक डेटा की मात्रा है।

असल में मैं एक पाइथन स्क्रिप्ट बनाने का प्रयास कर रहा हूं जिसे मैं कह सकता हूं; उदाहरण के लिए, मुझे फ़ाइल की 5000 अंतिम पंक्तियां दें। यह फिर से तर्कों को संभालने में बुनियादी है और यह सब कुछ भी विशेष नहीं है, मैं ऐसा कर सकता हूं।

लेकिन मैं फाइल रीडर को फ़ाइल के अंत से निर्दिष्ट लाइनों की मात्रा को केवल पढ़ने के लिए कैसे परिभाषित या बता सकता हूं? मैं huuuuuuge फ़ाइल की शुरुआत में लाइनों की मात्रा को छोड़ने की कोशिश कर रहा हूं क्योंकि मुझे उन लोगों में दिलचस्पी नहीं है और ईमानदार होने के लिए, txt फ़ाइल से 15GB लाइनों को पढ़ने में बहुत लंबा समय लगता है। क्या गलती करने का कोई तरीका है .. फ़ाइल के अंत से पढ़ना शुरू करें? क्या यह अर्थसार्थक भी है?

यह सब 15 जीबी फ़ाइल पढ़ने के मुद्दे पर उबाल जाता है, रेखा से रेखा बहुत लंबी होती है। तो मैं शुरुआत में पहले से ही अनावश्यक डेटा (कम से कम मेरे लिए अनावश्यक) को छोड़ना चाहता हूं और केवल उस फ़ाइल के अंत से लाइनों की मात्रा को पढ़ना चाहता हूं जिसे मैं पढ़ना चाहता हूं।

स्पष्ट उत्तर फ़ाइल से अन्य फाइलों को मैन्युअल रूप से प्रतिलिपि बनाने के लिए है, लेकिन इस अर्ध-जादुई तरीके से फ़ाइल के अंत से पाइथन के साथ एन लाइनों को पढ़ने के लिए एक तरीका है ?

+0

क्या ओएस आप का उपयोग कर रहे हैं? –

+2

कोई सीधा जवाब नहीं है, लेकिन यदि आप; निक्स का उपयोग कर रहे हैं तो आप इसके बजाय stdin से इनपुट स्वीकार कर सकते हैं और 'tail hugefile.txt -n1000' का उपयोग कर डेटा भेज सकते हैं। python myprog.py' – moopet

+1

डुप्लिकेट प्रश्न पर उत्तर देखें। पहला अपेक्षाकृत प्लेटफ़ॉर्म-स्वतंत्र है, दूसरा यूनिक्स-आधारित सिस्टम पर अच्छी तरह से काम करता है ('पूंछ' कमांड का उपयोग करके @moopet सुझाया गया है)। –

उत्तर

-1

इस बिंदु पर पसंदीदा विधि नौकरी के लिए यूनिक्स की पूंछ का उपयोग करना था और पायथन को एसडी इनपुट के माध्यम से इनपुट स्वीकार करने के लिए संशोधित करना था।

tail hugefile.txt -n1000 | python magic.py 

यह सेक्सी नहीं है लेकिन कम से कम यह नौकरी का ख्याल रखता है। बड़ी फाइल को संभालने के लिए बोझ का एक बड़ा हिस्सा है, मैंने पाया। कम से कम मेरे अजगर कौशल के लिए। तो फाइलसाइज़ को काटने के लिए इसे निक्स जादू का चुटकी जोड़ने के लिए बहुत आसान था। पूंछ मेरे लिए नया था। कुछ सीख लिया और फिर से मेरे लाभ के लिए टर्मिनल का उपयोग करने का एक और तरीका पता लगाया। आप सभी को धन्यवाद।

4

यूनिक्स को यह फार्म आउट:

import os 
os.popen('tail -n 1000 filepath').read() 

उपयोग os.popen के बजाय subprocess.Popen अगर आप भले ही मैं पसंद करेंगे stderr (और कुछ अन्य सुविधाओं)

+0

इस धागे में बहुत सारे विचारशील उत्तर हैं लेकिन व्यावहारिक उद्देश्यों के लिए आपका उत्तर सबसे प्रासंगिक प्रतीत होता है - एक उच्च रैंकिंग का हकदार है! – isosceleswheel

0

उपयोग करने में सक्षम होने की जरूरत है 'पूंछ' समाधान - यदि आप प्रति पंक्ति वर्णों की अधिकतम संख्या जानते हैं तो आप फ़ाइल का आकार प्राप्त करके एक और संभावित समाधान लागू कर सकते हैं, एक फ़ाइल हैंडलर खोल सकते हैं और 'खोज' विधि का उपयोग कर सकते हैं जो कि आप देख रहे कुछ वर्णों की संख्या के साथ के लिये।

यह अंतिम कोड इस तरह से कुछ देखना चाहिए - बस यह बताने के लिए कि मैं पूंछ समाधान क्यों पसंद करता हूं :) goodluck!

MAX_CHARS_PER_LINE = 80 
size_of_file = os.path.getsize('15gbfile.txt') 
file_handler = file.open('15gbfile.txt', "rb") 
seek_index = size_of_file - (number_of_requested_lines * MAX_CHARS_PER_LINE) 
file_handler.seek(seek_index) 
buffer = file_handler.read() 

आप जो बफर पढ़ते हैं उसकी नई पंक्तियों का विश्लेषण करके आप इस कोड को बेहतर बना सकते हैं। गुड लक (और आप पूंछ समाधान का उपयोग करना चाहिए ;-) मैं काफी यकीन है कि आप हर ओएस के लिए पूंछ प्राप्त कर सकते हैं कर रहा हूँ)

11

आप अंत फ़ाइल के को तलाश करने के लिए है, तो से ब्लॉक में कुछ हिस्सा पढ़ा की जरूरत है अंत, लाइनों की गिनती, जब तक आपको n लाइनों को पढ़ने के लिए पर्याप्त नई लाइनें नहीं मिल जातीं।

असल में, आप पूंछ का एक सरल रूप फिर से कार्यान्वित कर रहे हैं।

यहाँ कुछ हल्के से परीक्षण किया कोड सिर्फ इतना है कि है कि है:

import os, errno 

def lastlines(hugefile, n, bsize=2048): 
    # get newlines type, open in universal mode to find it 
    with open(hugefile, 'rU') as hfile: 
     if not hfile.readline(): 
      return # empty, no point 
     sep = hfile.newlines # After reading a line, python gives us this 
    assert isinstance(sep, str), 'multiple newline types found, aborting' 

    # find a suitable seek position in binary mode 
    with open(hugefile, 'rb') as hfile: 
     hfile.seek(0, os.SEEK_END) 
     linecount = 0 
     pos = 0 

     while linecount <= n + 1: 
      # read at least n lines + 1 more; we need to skip a partial line later on 
      try: 
       hfile.seek(-bsize, os.SEEK_CUR)   # go backwards 
       linecount += hfile.read(bsize).count(sep) # count newlines 
       hfile.seek(-bsize, os.SEEK_CUR)   # go back again 
      except IOError, e: 
       if e.errno == errno.EINVAL: 
        # Attempted to seek past the start, can't go further 
        bsize = hfile.tell() 
        hfile.seek(0, os.SEEK_SET) 
        linecount += hfile.read(bsize).count(sep) 
        break 
       raise # Some other I/O exception, re-raise 
      pos = hfile.tell() 

    # Re-open in text mode 
    with open(hugefile, 'r') as hfile: 
     hfile.seek(pos, os.SEEK_SET) # our file position from above 

     for line in hfile: 
      # We've located n lines *or more*, so skip if needed 
      if linecount > n: 
       linecount -= 1 
       continue 
      # The rest we yield 
      yield line 
+0

आप उपज लाइनों को कैसे मुद्रित करते हैं? – Superdooperhero

+0

मुझे देता है: ट्रेसबैक (सबसे हालिया कॉल अंतिम): फ़ाइल "tail3.py", लाइन 45, अंतिम पंक्तियां (आर "ई: \ D_Backup \ डाउनलोड \ googlebooks-eng-all-2gram-20120701-_NOUN_" 1000, bsize = 2048) फाइल "tail3.py", लाइन 21, आखिरी पंक्तियों में लाइनकाउंट + = hfile.read (bsize) .count (sep) # गिनती न्यूलाइन टाइप एरर: बाइट्स जैसी ऑब्जेक्ट की आवश्यकता है, न कि ' str ' – Superdooperhero

+1

@Superdooperhero: कोड पायथन 2 के लिए लिखा गया था, पायथन 3 नहीं। आपको इसके बजाय' बाइट्स 'ऑब्जेक्ट प्राप्त करने के लिए 'sep.encode()' का उपयोग करना होगा। –

संबंधित मुद्दे