Python获得最后一行

时间:2016-10-08 16:02:50

标签: python search raspberry-pi pulse

在监测项目上,我需要计算来自脉冲计的脉冲。我已经找到了一些解决方案,我一直在努力适应我的需求。

这是在Raspberry Pi上运行的python脚本:

#!/usr/bin/env python

import RPi.GPIO as GPIO
import datetime
import sys
import signal
from subprocess import check_output

#verbose = True     # global variable

############################################################################################################
############################################################################################################

def printusage(progname):
        print progname + ' <gpio-pin-number> <filename> [debug]'
        print 'Example usage: ' 
    print progname + ' 23 /path/to/mylogfile'
        print progname + ' 23 /path/to/mylogfile debug'
    sys.exit(-1)

def signal_handler(signal, frame):
        if verbose:
        print('You pressed Ctrl+C, so exiting')
    GPIO.cleanup()
        sys.exit(0)


def readvalue(myworkfile):
    try:
        f = open(myworkfile, 'ab+')     # open for reading. If it does not exist, create it
        line=subprocess.check_output(['tail','-f','-1',f])
        elmts=line.split(" ")
        value = int(elmts[2])   
    except:
        value = 0               # if something went wrong, reset to 0
    #print "old value is", value
    f.close()   # close for reading
    return value


def writevalue(myworkfile,value):
    f = open(myworkfile, 'a')
    f.write((str(datetime.datetime.now())+' '+str(value)+'\r\n'))   # timestamp
    f.close()   

############################################################################################################
############################################################################################################

######### Initialization


#### get input parameters:

try:
    mygpiopin = int(sys.argv[1])
    logfile = sys.argv[2]
except:
    printusage(sys.argv[0])

verbose = False
try:
    if sys.argv[3] == 'debug':
        verbose = True
        print "Verbose is On"
    else:
        printusage(sys.argv[0])
except:
    pass

#### if verbose, print some info to stdout

if verbose:
    print "GPIO is " + str(mygpiopin)
    print "Logfile is " + logfile
    print "Current value is " + str(readvalue(logfile))


#### setup

GPIO.setmode(GPIO.BCM)
GPIO.setup(mygpiopin, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)

signal.signal(signal.SIGINT, signal_handler)    # SIGINT = interrupt by CTRL-C


########## Main Loop 

while True:
    # wait for pin going up
    GPIO.wait_for_edge(mygpiopin, GPIO.RISING)

    # read value from file
    counter=readvalue(logfile) + 1
    if verbose:
        print "New value is", counter

    # write value to file
    writevalue(logfile,counter)

    # and wait for pin going down
    GPIO.wait_for_edge(mygpiopin, GPIO.FALLING)

############################################################################################################
############################################################################################################

我想要注册最后一个索引,然后递增它,但到目前为止我测试的所有内容都将循环停留在索引1上。

我无法使用“更重”的方法来查找最后一行,例如浏览整个文件,因为随着时间的推移,它只会变得越来越重,我不能错过一个脉冲。

我对编程很陌生,所以感谢你的帮助!

编辑:结果文件如下所示:

2016-10-08 16:54:23.072469 1
2016-10-08 16:54:23.462465 1
2016-10-08 16:54:23.777977 1
2016-10-08 16:54:24.010045 1
2016-10-08 16:54:24.194032 1
2016-10-08 16:54:24.388120 1
2016-10-08 16:54:24.549389 1
2016-10-08 16:54:24.737994 1
2016-10-08 16:54:24.959462 1
2016-10-08 16:54:25.164638 1
2016-10-08 16:54:25.351850 1
2016-10-08 16:54:25.536655 1
2016-10-08 16:54:25.716214 1
2016-10-08 16:54:25.794152 1
2016-10-08 17:06:13.506531 1
2016-10-08 17:06:14.097642 1
2016-10-08 17:06:14.211579 1
2016-10-08 17:06:15.237852 1
2016-10-08 17:06:15.752239 1
2016-10-08 17:06:16.320419 1
2016-10-08 17:06:16.842906 1
2016-10-08 17:06:17.391121 1
2016-10-08 17:06:17.851521 1
2016-10-08 17:06:18.444486 1
2016-10-08 17:06:18.858358 1

3 个答案:

答案 0 :(得分:0)

要读取大文件的最后一行,请选择文件末尾附近的位置并阅读。如果那里没有换行符,请稍微再看一遍。

然后找到最后一个换行符,剩下的就是你的最后一行。

EXPECTED_MAX_LINE_SIZE = 500  # this should be both small enough and big enough

def get_last_line(f):
    end = f.seek(0, os.SEEK_END)   # detect file size
    pos = end-EXPECTED_MAX_LINE_SIZE
    if pos < 0: pos = 0
    f.seek(pos, os.SEEK_SET)
    end_of_file = f.read(EXPECTED_MAX_LINE_SIZE)

    # TODO: check if '\n' is not there and read some more

    return end_of_file.splitlines()[-1]

答案 1 :(得分:0)

你的逻辑过于复杂,如果你将不同时间运行脚本,只需将最后一个索引存储在一个单独的文件中不断覆盖:

 def next_index(index):
    with open(index, 'a+') as f:  # open for reading. If it does not exist, create it
        val = int(next(f, -1)) + 1 # first run value will be 0
    open(index,"w").write(str(val)) # overwrite
    return val

如果在其他地方创建了值,那么只需在那里写,只需确保用w覆盖之前的值。

答案 2 :(得分:0)

我不认为这就是Padraic Cunningham的意思,但我设法通过使用两个文件来解决我的问题,一个用于记录更新的索引值,另一个用于存储值:

#!/usr/bin/env python

import RPi.GPIO as GPIO
import datetime
import sys
import signal

#verbose = True     # global debug variable

############################################################################################################

def printusage(progname): #show how to use the script
    print progname + ' <gpio-pin-number> <index file> <store file> [debug]'
    print 'Example usage: ' 
    print progname + ' 23 /path/to/mylogfile /path/to/storefile'
    print progname + ' 23 /path/to/mylogfile /path/to/storefile debug'
    sys.exit(-1)

def signal_handler(signal, frame): #exiting the script
    if verbose:
        print('You pressed Ctrl+C, so exiting')
    GPIO.cleanup()
    sys.exit(0)


def readvalue(myworkfile):
    try:
        f = open(myworkfile, 'ab+')     # open for reading. If it does not exist, create it
        line=f.readline() #read the first and only line of the file
        elmts=line.split(" ") # the format is <yyyy-mm-dd hh:mm:ss.ssssss indexvalue>
        value = int(elmts[2]) #get the index value
    except:
        value = 0               # if something went wrong, reset to 0
    #print "old value is", value
    f.close()   # close for reading
    return value


def writevalue(myworkfile,value):
    f = open(myworkfile, 'w') #overwrite the value
    f.write((str(datetime.datetime.now())+' '+str(value)))  # timestamp + data
    f.close()   

def store_value(index_file,index_value):
    f=open(index_file, 'a+')
    f.write(str(datetime.datetime.now())+' '+str(index_value)+'\r\n') #store timestamp + data
    f.close()

############################################################################################################

######### Initialization
#### get input parameters 
try:
    mygpiopin = int(sys.argv[1])
    logfile = sys.argv[2]
    storefile=sys.argv[3]
except:
    printusage(sys.argv[0])

verbose = False
try:
    if sys.argv[4] == 'debug':
        verbose = True
        print "Verbose is On"
    else:
        printusage(sys.argv[0])
except:
    pass

if verbose: #### if verbose, print some info to stdout
    print "GPIO is " + str(mygpiopin)
    print "Logfile is " + logfile
    print "Storefile is " + storefile
    print "Current value is " + str(readvalue(logfile))

#### SETUP
GPIO.setmode(GPIO.BCM)
GPIO.setup(mygpiopin, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
signal.signal(signal.SIGINT, signal_handler)    # SIGINT = interrupt by CTRL-C

########## Main Loop #####

while True:
    GPIO.wait_for_edge(mygpiopin, GPIO.RISING) # wait for pin going up
    counter=readvalue(logfile) + 1 # read value from file and increment index
    if verbose:
        print "New value is", counter
    writevalue(logfile,counter) # write value to logfile
    store_value(storefile,counter)  # store value in storefile
    GPIO.wait_for_edge(mygpiopin, GPIO.FALLING) # and wait for pin going down
############################################################################################################

感谢您的帮助!