แยกช่วงเวลาอย่างรวดเร็วจาก syslog logfile?


12

ฉันมีไฟล์บันทึกการทำงานในรูปแบบ syslog มาตรฐาน ดูเหมือนว่านี้ยกเว้นหลายร้อยบรรทัดต่อวินาที:

Jan 11 07:48:46 blahblahblah...
Jan 11 07:49:00 blahblahblah...
Jan 11 07:50:13 blahblahblah...
Jan 11 07:51:22 blahblahblah...
Jan 11 07:58:04 blahblahblah...

มันไม่หมุนในเวลาเที่ยงคืน แต่จะไม่มีวันเกินสองวัน

ฉันมักจะต้องแยกเวลาออกจากไฟล์นี้ ฉันต้องการเขียนสคริปต์วัตถุประสงค์ทั่วไปสำหรับสิ่งนี้ที่ฉันสามารถเรียกเช่น:

$ timegrep 22:30-02:00 /logs/something.log

... และดึงเส้นจากเวลา 22:30 น. ขึ้นไปข้ามขอบเขตเที่ยงคืนจนถึงตี 2 ในวันถัดไป

มีข้อแม้อยู่เล็กน้อย:

  • ฉันไม่ต้องการที่จะต้องพิมพ์วันที่ลงบนบรรทัดคำสั่งอีกต่อไป โปรแกรมควรฉลาดพอที่จะเข้าใจได้
  • รูปแบบวันที่บันทึกไม่รวมปีดังนั้นจึงควรเดาตามปีปัจจุบัน แต่ก็ทำสิ่งที่ถูกต้องในวันปีใหม่
  • ฉันต้องการให้มันเร็ว - ควรใช้ความจริงที่ว่าบรรทัดนั้นมีไว้เพื่อค้นหาในไฟล์และใช้การค้นหาแบบไบนารี

ก่อนที่ฉันจะใช้เวลาเขียนสิ่งนี้มันมีอยู่แล้วหรือเปล่า?

คำตอบ:


9

อัปเดต:ฉันได้แทนที่รหัสดั้งเดิมด้วยรุ่นที่อัปเดตแล้วพร้อมการปรับปรุงมากมาย มาเรียกคุณภาพอัลฟ่านี้กัน (จริงหรือ?)

รุ่นนี้รวมถึง:

  • การจัดการตัวเลือกบรรทัดคำสั่ง
  • การตรวจสอบรูปแบบวันที่บรรทัดคำสั่ง
  • บางtryช่วงตึก
  • การอ่านบรรทัดถูกย้ายไปยังฟังก์ชัน

ข้อความต้นฉบับ:

คุณรู้อะไรดี "แสวงหาและท่านจะพบ! นี่คือโปรแกรม Python ที่พยายามค้นหาไฟล์และใช้การค้นหาแบบไบนารีมากกว่าหรือน้อยกว่า มันมากเร็วกว่าสคริปต์ AWK ที่ที่คนอื่นเขียน

มันคือคุณภาพพรีอัลฟา ควรมีtryการตรวจสอบบล็อกและการป้อนข้อมูลและการทดสอบมากมายและไม่ต้องสงสัยเลยว่า Pythonic จะมีมากขึ้น แต่นี่มันเพื่อความสนุกของคุณ โอ้และมันถูกเขียนขึ้นสำหรับ Python 2.6

รหัสใหม่:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# timegrep.py by Dennis Williamson 20100113
# in response to http://serverfault.com/questions/101744/fast-extraction-of-a-time-range-from-syslog-logfile

# thanks to serverfault user http://serverfault.com/users/1545/mike
# for the inspiration

# Perform a binary search through a log file to find a range of times
# and print the corresponding lines

# tested with Python 2.6

# TODO: Make sure that it works if the seek falls in the middle of
#       the first or last line
# TODO: Make sure it's not blind to a line where the sync read falls
#       exactly at the beginning of the line being searched for and
#       then gets skipped by the second read
# TODO: accept arbitrary date

# done: add -l long and -s short options
# done: test time format

version = "0.01a"

import os, sys
from stat import *
from datetime import date, datetime
import re
from optparse import OptionParser

# Function to read lines from file and extract the date and time
def getdata():
    """Read a line from a file

    Return a tuple containing:
        the date/time in a format such as 'Jan 15 20:14:01'
        the line itself

    The last colon and seconds are optional and
    not handled specially

    """
    try:
        line = handle.readline(bufsize)
    except:
        print("File I/O Error")
        exit(1)
    if line == '':
        print("EOF reached")
        exit(1)
    if line[-1] == '\n':
        line = line.rstrip('\n')
    else:
        if len(line) >= bufsize:
            print("Line length exceeds buffer size")
        else:
            print("Missing newline")
        exit(1)
    words = line.split(' ')
    if len(words) >= 3:
        linedate = words[0] + " " + words[1] + " " + words[2]
    else:
        linedate = ''
    return (linedate, line)
# End function getdata()

# Set up option handling
parser = OptionParser(version = "%prog " + version)

parser.usage = "\n\t%prog [options] start-time end-time filename\n\n\
\twhere times are in the form hh:mm[:ss]"

parser.description = "Search a log file for a range of times occurring yesterday \
and/or today using the current time to intelligently select the start and end. \
A date may be specified instead. Seconds are optional in time arguments."

parser.add_option("-d", "--date", action = "store", dest = "date",
                default = "",
                help = "NOT YET IMPLEMENTED. Use the supplied date instead of today.")

parser.add_option("-l", "--long", action = "store_true", dest = "longout",
                default = False,
                help = "Span the longest possible time range.")

parser.add_option("-s", "--short", action = "store_true", dest = "shortout",
                default = False,
                help = "Span the shortest possible time range.")

parser.add_option("-D", "--debug", action = "store", dest = "debug",
                default = 0, type = "int",
                help = "Output debugging information.\t\t\t\t\tNone (default) = %default, Some = 1, More = 2")

(options, args) = parser.parse_args()

if not 0 <= options.debug <= 2:
    parser.error("debug level out of range")
else:
    debug = options.debug    # 1 = print some debug output, 2 = print a little more, 0 = none

if options.longout and options.shortout:
    parser.error("options -l and -s are mutually exclusive")

if options.date:
    parser.error("date option not yet implemented")

if len(args) != 3:
    parser.error("invalid number of arguments")

start = args[0]
end   = args[1]
file  = args[2]

# test for times to be properly formatted, allow hh:mm or hh:mm:ss
p = re.compile(r'(^[2][0-3]|[0-1][0-9]):[0-5][0-9](:[0-5][0-9])?$')

if not p.match(start) or not p.match(end):
    print("Invalid time specification")
    exit(1)

# Determine Time Range
yesterday = date.fromordinal(date.today().toordinal()-1).strftime("%b %d")
today     = datetime.now().strftime("%b %d")
now       = datetime.now().strftime("%R")

if start > now or start > end or options.longout or options.shortout:
    searchstart = yesterday
else:
    searchstart = today

if (end > start > now and not options.longout) or options.shortout:
    searchend = yesterday
else:
    searchend = today

searchstart = searchstart + " " + start
searchend = searchend + " " + end

try:
    handle = open(file,'r')
except:
    print("File Open Error")
    exit(1)

# Set some initial values
bufsize = 4096  # handle long lines, but put a limit them
rewind  =  100  # arbitrary, the optimal value is highly dependent on the structure of the file
limit   =   75  # arbitrary, allow for a VERY large file, but stop it if it runs away
count   =    0
size    =    os.stat(file)[ST_SIZE]
beginrange   = 0
midrange     = size / 2
oldmidrange  = midrange
endrange     = size
linedate     = ''

pos1 = pos2  = 0

if debug > 0: print("File: '{0}' Size: {1} Today: '{2}' Now: {3} Start: '{4}' End: '{5}'".format(file, size, today, now, searchstart, searchend))

# Seek using binary search
while pos1 != endrange and oldmidrange != 0 and linedate != searchstart:
    handle.seek(midrange)
    linedate, line = getdata()    # sync to line ending
    pos1 = handle.tell()
    if midrange > 0:             # if not BOF, discard first read
        if debug > 1: print("...partial: (len: {0}) '{1}'".format((len(line)), line))
        linedate, line = getdata()

    pos2 = handle.tell()
    count += 1
    if debug > 0: print("#{0} Beg: {1} Mid: {2} End: {3} P1: {4} P2: {5} Timestamp: '{6}'".format(count, beginrange, midrange, endrange, pos1, pos2, linedate))
    if  searchstart > linedate:
        beginrange = midrange
    else:
        endrange = midrange
    oldmidrange = midrange
    midrange = (beginrange + endrange) / 2
    if count > limit:
        print("ERROR: ITERATION LIMIT EXCEEDED")
        exit(1)

if debug > 0: print("...stopping: '{0}'".format(line))

# Rewind a bit to make sure we didn't miss any
seek = oldmidrange
while linedate >= searchstart and seek > 0:
    if seek < rewind:
        seek = 0
    else:
        seek = seek - rewind
    if debug > 0: print("...rewinding")
    handle.seek(seek)

    linedate, line = getdata()    # sync to line ending
    if debug > 1: print("...junk: '{0}'".format(line))

    linedate, line = getdata()
    if debug > 0: print("...comparing: '{0}'".format(linedate))

# Scan forward
while linedate < searchstart:
    if debug > 0: print("...skipping: '{0}'".format(linedate))
    linedate, line = getdata()

if debug > 0: print("...found: '{0}'".format(line))

if debug > 0: print("Beg: {0} Mid: {1} End: {2} P1: {3} P2: {4} Timestamp: '{5}'".format(beginrange, midrange, endrange, pos1, pos2, linedate))

# Now that the preliminaries are out of the way, we just loop,
#     reading lines and printing them until they are
#     beyond the end of the range we want

while linedate <= searchend:
    print line
    linedate, line = getdata()

if debug > 0: print("Start: '{0}' End: '{1}'".format(searchstart, searchend))
handle.close()

ว้าว. ฉันจำเป็นต้องเรียนรู้ Python จริงๆ ...
Stefan Lasiewski

@Dennis วิลเลียมสัน: if debug > 0: print("File: '{0}' Size: {1} Today: '{2}' Now: {3} Start: '{4}' End: '{5}'".format(file, size, today, now, searchstar$ผมเห็นโฆษณาที่มี นี้searchstarควรจะจบลงด้วย$หรือว่าพิมพ์ผิดหรือไม่? ฉันได้รับข้อผิดพลาดทางไวยากรณ์ของบรรทัดนี้ (บรรทัด 159)
Stefan Lasiewski

@ Stefan ))ฉันแทนที่ด้วย
Bill Weiss

@tefan: ขอบคุณ มันเป็นตัวพิมพ์ที่ฉันได้รับการแก้ไข สำหรับการอ้างอิงอย่างรวดเร็วที่$ควรจะเป็นt, searchend))ดังนั้นจึงกล่าวว่า... searchstart, searchend))
หยุดชั่วคราวจนกว่าจะมีประกาศ

@Stefan: ขอโทษด้วย ฉันคิดว่ามันเข้าใจ
หยุดชั่วคราวจนกว่าจะมีการแจ้งให้ทราบต่อไป

0

จากการค้นหาอย่างรวดเร็วบนอินเทอร์เน็ตมีสิ่งที่แยกตามคำหลัก (เช่นไฟไหม้หรือเช่น :) แต่ไม่มีอะไรที่แยกช่วงวันที่จากไฟล์

ดูเหมือนไม่ยากที่จะทำสิ่งที่คุณเสนอ:

  1. ค้นหาเวลาเริ่มต้น
  2. พิมพ์บรรทัดนั้น
  3. หากเวลาสิ้นสุด <เวลาเริ่มต้นและวันที่ของบรรทัดคือ> end และ <start ให้หยุด
  4. หากเวลาสิ้นสุดคือ> เวลาเริ่มต้นและวันที่ของบรรทัดคือ> end ให้หยุด

ดูเหมือนตรงไปตรงมาและฉันสามารถเขียนเพื่อคุณถ้าคุณไม่รังเกียจทับทิม :)


ฉันไม่รังเกียจ Ruby แต่ # 1 ไม่ตรงไปตรงมาหากคุณต้องการทำมันอย่างมีประสิทธิภาพในไฟล์ขนาดใหญ่ - คุณต้องหา () ไปยังจุดกึ่งกลางค้นหาบรรทัดที่ใกล้ที่สุดดูว่ามันเริ่มต้นอย่างไรและทำซ้ำกับ จุดกึ่งกลางใหม่ มันไม่มีประสิทธิภาพเกินกว่าที่จะดูทุกบรรทัด
ไมค์

คุณพูดว่าใหญ่ แต่ไม่ได้ระบุขนาดจริง ใหญ่แค่ไหน ที่แย่ไปกว่านั้นหากมีหลายวันที่เกี่ยวข้องมันจะค่อนข้างง่ายที่จะค้นหาสิ่งที่ผิดเพียงแค่ใช้เวลา ท้ายที่สุดถ้าคุณข้ามเขตแดนวันวันที่สคริปต์กำลังทำงานอยู่จะแตกต่างจากเวลาเริ่มต้นเสมอ ไฟล์จะพอดีกับหน่วยความจำผ่าน mmap () หรือไม่
Michael Graff

ประมาณ 30 GB บนดิสก์ที่ติดตั้งผ่านเครือข่าย
ไมค์

0

สิ่งนี้จะพิมพ์ช่วงของรายการระหว่างเวลาเริ่มต้นและเวลาสิ้นสุดโดยพิจารณาจากความสัมพันธ์กับเวลาปัจจุบัน ("ตอนนี้")

การใช้งาน:

timegrep [-l] start end filename

ตัวอย่าง:

$ timegrep 18:47 03:22 /some/log/file

-l(ยาว) ตัวเลือกที่เป็นสาเหตุที่ทำให้การส่งออกเป็นไปได้ที่ยาวที่สุด เวลาเริ่มต้นจะถูกตีความว่าเป็นเมื่อวานนี้หากค่าชั่วโมงและนาทีของเวลาเริ่มต้นน้อยกว่าทั้งเวลาสิ้นสุดและตอนนี้ เวลาสิ้นสุดจะถูกตีความว่าเป็นวันนี้หากทั้งเวลาเริ่มต้นและเวลาสิ้นสุด HH: MM มีค่ามากกว่า "ตอนนี้"

สมมติว่า "ตอนนี้" คือ "Jan 11 19:00" นี่เป็นตัวอย่างการตีความเวลาเริ่มต้นและสิ้นสุดที่หลากหลาย (โดยไม่มี-lยกเว้นดังที่ระบุไว้):

เริ่มต้นช่วงสิ้นสุดเริ่มต้นช่วงสิ้นสุด
19:01 23:59 10 ม.ค. 10
19:01 00:00 10 มกราคม 11 มกราคม
00:00 18:59 11 มกราคม 11 มกราคม
18:59 18:58 10 ม.ค. 10
19:01 23:59 10 มกราคม 11 # -l
00:00 18:59 10 มกราคม 11 # -l
18:59 19:01 10 ม.ค. 11 # -l

สคริปต์เกือบทั้งหมดได้รับการตั้งค่า สองบรรทัดสุดท้ายทำงานทั้งหมด

คำเตือน: ไม่มีการตรวจสอบข้อโต้แย้งหรือการตรวจสอบข้อผิดพลาด กรณีขอบยังไม่ได้รับการทดสอบอย่างละเอียด สิ่งนี้เขียนโดยใช้gawkAWK รุ่นอื่น ๆ

#!/usr/bin/awk -f
BEGIN {
    arg=1
    if ( ARGV[arg] == "-l" ) {
        long = 1
        ARGV[arg++] = ""
    }
    start = ARGV[arg]
    ARGV[arg++] = ""
    end = ARGV[arg]
    ARGV[arg++] = ""

    yesterday = strftime("%b %d", mktime(strftime("%Y %m %d -24 00 00")))
    today = strftime("%b %d")
    now = strftime("%R")

    if ( start > now || start > end || long )
        startdate = yesterday
    else
        startdate = today

    if ( end > now && end > start && start > now && ! long )
        enddate = yesterday
    else
        enddate = today
    fi

startdate = startdate " " start
enddate = enddate " " end
}

$1 " " $2 " " $3 > enddate {exit}
$1 " " $2 " " $3 >= startdate {print}

ฉันคิดว่า AWK มีประสิทธิภาพมากในการค้นหาไฟล์ ฉันไม่คิดว่าสิ่งอื่นใดคือจำเป็นต้องไปได้เร็วขึ้นในการค้นหาunindexedไฟล์ข้อความ


ดูเหมือนว่าคุณจะมองข้ามจุด bullet ที่สามของฉัน บันทึกอยู่ในลำดับที่ 30 GB - ถ้าบรรทัดแรกของไฟล์คือ 7:00 และบรรทัดสุดท้ายคือ 23:00 และฉันต้องการชิ้นระหว่าง 22:00 ถึง 22:01 ฉันไม่ต้องการ สคริปต์จะดูทุกบรรทัดระหว่าง 7:00 ถึง 22:00 ฉันต้องการให้มันประมาณว่ามันจะหาจุดนั้นและทำการประเมินใหม่จนกว่ามันจะพบ
ไมค์

ฉันไม่ได้มองข้าม ฉันแสดงความคิดเห็นในวรรคสุดท้าย
หยุดชั่วคราวจนกว่าจะมีการแจ้งให้ทราบต่อไป

0

โปรแกรม C ++ ที่ใช้การค้นหาแบบไบนารี - มันจะต้องมีการแก้ไขง่ายๆ (เช่นการเรียก strptime) เพื่อทำงานกับวันที่ของข้อความ

http://gitorious.org/bs_grep/

ฉันมีรุ่นก่อนหน้าพร้อมการรองรับวันที่ข้อความ แต่ก็ยังช้าเกินไปสำหรับขนาดของไฟล์บันทึกของเรา การทำโปรไฟล์กล่าวว่ามากกว่า 90% ของเวลาถูกใช้เป็น strptime ดังนั้นเราเพิ่งแก้ไขรูปแบบการบันทึกเพื่อรวมการประทับเวลาแบบ unix ที่เป็นตัวเลขด้วย


0

แม้ว่าคำตอบนี้จะสายเกินไปมันอาจเป็นประโยชน์กับบางคน

ฉันได้แปลงรหัสจาก @Dennis Williamson เป็นคลาส Python ที่สามารถใช้สำหรับสิ่งอื่น ๆ ของหลาม

ฉันได้เพิ่มการสนับสนุนสำหรับรองรับหลายวัน

import os
from stat import *
from datetime import date, datetime
import re

# @TODO Support for rotated log files - currently using the current year for 'Jan 01' dates.
class LogFileTimeParser(object):
    """
    Extracts parts of a log file based on a start and enddate
    Uses binary search logic to speed up searching

    Common usage: validate log files during testing

    Faster than awk parsing for big log files
    """
    version = "0.01a"

    # Set some initial values
    BUF_SIZE = 4096  # self.handle long lines, but put a limit to them
    REWIND = 100  # arbitrary, the optimal value is highly dependent on the structure of the file
    LIMIT = 75  # arbitrary, allow for a VERY large file, but stop it if it runs away

    line_date = ''
    line = None
    opened_file = None

    @staticmethod
    def parse_date(text, validate=True):
        # Supports Aug 16 14:59:01 , 2016-08-16 09:23:09 Jun 1 2005  1:33:06PM (with or without seconds, miliseconds)
        for fmt in ('%Y-%m-%d %H:%M:%S %f', '%Y-%m-%d %H:%M:%S', '%Y-%m-%d %H:%M',
                    '%b %d %H:%M:%S %f', '%b %d %H:%M', '%b %d %H:%M:%S',
                    '%b %d %Y %H:%M:%S %f', '%b %d %Y %H:%M', '%b %d %Y %H:%M:%S',
                    '%b %d %Y %I:%M:%S%p', '%b %d %Y %I:%M%p', '%b %d %Y %I:%M:%S%p %f'):
            try:
                if fmt in ['%b %d %H:%M:%S %f', '%b %d %H:%M', '%b %d %H:%M:%S']:

                    return datetime.strptime(text, fmt).replace(datetime.now().year)
                return datetime.strptime(text, fmt)
            except ValueError:
                pass
        if validate:
            raise ValueError("No valid date format found for '{0}'".format(text))
        else:
            # Cannot use NoneType to compare datetimes. Using minimum instead
            return datetime.min

    # Function to read lines from file and extract the date and time
    def read_lines(self):
        """
        Read a line from a file
        Return a tuple containing:
            the date/time in a format supported in parse_date om the line itself
        """
        try:
            self.line = self.opened_file.readline(self.BUF_SIZE)
        except:
            raise IOError("File I/O Error")
        if self.line == '':
            raise EOFError("EOF reached")
        # Remove \n from read lines.
        if self.line[-1] == '\n':
            self.line = self.line.rstrip('\n')
        else:
            if len(self.line) >= self.BUF_SIZE:
                raise ValueError("Line length exceeds buffer size")
            else:
                raise ValueError("Missing newline")
        words = self.line.split(' ')
        # This results into Jan 1 01:01:01 000000 or 1970-01-01 01:01:01 000000
        if len(words) >= 3:
            self.line_date = self.parse_date(words[0] + " " + words[1] + " " + words[2],False)
        else:
            self.line_date = self.parse_date('', False)
        return self.line_date, self.line

    def get_lines_between_timestamps(self, start, end, path_to_file, debug=False):
        # Set some initial values
        count = 0
        size = os.stat(path_to_file)[ST_SIZE]
        begin_range = 0
        mid_range = size / 2
        old_mid_range = mid_range
        end_range = size
        pos1 = pos2 = 0

        # If only hours are supplied
        # test for times to be properly formatted, allow hh:mm or hh:mm:ss
        p = re.compile(r'(^[2][0-3]|[0-1][0-9]):[0-5][0-9](:[0-5][0-9])?$')
        if p.match(start) or p.match(end):
            # Determine Time Range
            yesterday = date.fromordinal(date.today().toordinal() - 1).strftime("%Y-%m-%d")
            today = datetime.now().strftime("%Y-%m-%d")
            now = datetime.now().strftime("%R")
            if start > now or start > end:
                search_start = yesterday
            else:
                search_start = today
            if end > start > now:
                search_end = yesterday
            else:
                search_end = today
            search_start = self.parse_date(search_start + " " + start)
            search_end = self.parse_date(search_end + " " + end)
        else:
            # Set dates
            search_start = self.parse_date(start)
            search_end = self.parse_date(end)
        try:
            self.opened_file = open(path_to_file, 'r')
        except:
            raise IOError("File Open Error")
        if debug:
            print("File: '{0}' Size: {1} Start: '{2}' End: '{3}'"
                  .format(path_to_file, size, search_start, search_end))

        # Seek using binary search -- ONLY WORKS ON FILES WHO ARE SORTED BY DATES (should be true for log files)
        try:
            while pos1 != end_range and old_mid_range != 0 and self.line_date != search_start:
                self.opened_file.seek(mid_range)
                # sync to self.line ending
                self.line_date, self.line = self.read_lines()
                pos1 = self.opened_file.tell()
                # if not beginning of file, discard first read
                if mid_range > 0:
                    if debug:
                        print("...partial: (len: {0}) '{1}'".format((len(self.line)), self.line))
                    self.line_date, self.line = self.read_lines()
                pos2 = self.opened_file.tell()
                count += 1
                if debug:
                    print("#{0} Beginning: {1} Mid: {2} End: {3} P1: {4} P2: {5} Timestamp: '{6}'".
                          format(count, begin_range, mid_range, end_range, pos1, pos2, self.line_date))
                if search_start > self.line_date:
                    begin_range = mid_range
                else:
                    end_range = mid_range
                old_mid_range = mid_range
                mid_range = (begin_range + end_range) / 2
                if count > self.LIMIT:
                    raise IndexError("ERROR: ITERATION LIMIT EXCEEDED")
            if debug:
                print("...stopping: '{0}'".format(self.line))
            # Rewind a bit to make sure we didn't miss any
            seek = old_mid_range
            while self.line_date >= search_start and seek > 0:
                if seek < self.REWIND:
                    seek = 0
                else:
                    seek -= self.REWIND
                if debug:
                    print("...rewinding")
                self.opened_file.seek(seek)
                # sync to self.line ending
                self.line_date, self.line = self.read_lines()
                if debug:
                    print("...junk: '{0}'".format(self.line))
                self.line_date, self.line = self.read_lines()
                if debug:
                    print("...comparing: '{0}'".format(self.line_date))
            # Scan forward
            while self.line_date < search_start:
                if debug:
                    print("...skipping: '{0}'".format(self.line_date))
                self.line_date, self.line = self.read_lines()
            if debug:
                print("...found: '{0}'".format(self.line))
            if debug:
                print("Beginning: {0} Mid: {1} End: {2} P1: {3} P2: {4} Timestamp: '{5}'".
                      format(begin_range, mid_range, end_range, pos1, pos2, self.line_date))
            # Now that the preliminaries are out of the way, we just loop,
            # reading lines and printing them until they are beyond the end of the range we want
            while self.line_date <= search_end:
                # Exclude our 'Nonetype' values
                if not self.line_date == datetime.min:
                    print self.line
                self.line_date, self.line = self.read_lines()
            if debug:
                print("Start: '{0}' End: '{1}'".format(search_start, search_end))
            self.opened_file.close()
        # Do not display EOFErrors:
        except EOFError as e:
            pass
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.