开发者

Loop a string search until a string is found python

开发者 https://www.devze.com 2023-02-07 15:44 出处:网络
I thought this would be easy, after 3 hours of searching and trial and error it appears not to be easy.

I thought this would be easy, after 3 hours of searching and trial and error it appears not to be easy.

All I want to do is loop a search for a string until the string is found. I'm searc开发者_开发百科hing a log file for a string that appears when a condition arises e.g. when the string "function test 1" appears in the log I need to find it then execute another function.

Finding it is no problem, the problem is looping until it's found.

This finds perfectly:

for line in open(WebPath + SmokeTest): #these are variables I use to construct the path
    if 'readfalseloop2' in line:
            print True
            f = open(WebPath + SmokeTest,'a')
            f.write('<font color= "#347C2C">readfalseloop2</font><br />')
            f.close()
            break
    else:
        print False

I want to execute this until the word is found. Ideally I'd like to embed this in multiple functions, i don't want a separate def at this point.

I've not had success with any looping construct and YES I've looked at python docs, searched this site and ubuntu forum.


Nice code Andrew. I wasn't informed of the existence of the for/else possibility.

But to temper the activity of machine's processes, it is possible to avoid repeated opening and closing of the file, and it is preferable to cool down the frequency of the verification IMO

from time import sleep

with open(WebPath + SmokeTest,'a+') as f:
    while True:
        if 'readfalseloop2' in f.read():
            f.seek(0,1)
            f.write('\n<font color= "#347C2C">readfalseloop2</font><br />')
            print True
            break
        print '~',
        f.seek(0,0)
        sleep(2)

This code works, I tested it . But only if the changing is performed through another programm. When I tried to modify the file by inserting the

<font color= "#347C2C">readfalseloop2</font><br />

chain manually, Windows refused to close the file with the changing.

.

After the f.read() , the file's pointer f must be reactivated to make it possible to write the

<font color= "#347C2C">readfalseloop2</font><br />

chain at the end of the file's content.

I don't know in what consists this reactivation. I only know that if the f.seek(0,1) instruction isn't executed, the process can't switch from a 'read' mode to a 'write' mode.

f.seek(0,1) means "move of 0 characters from your current position"; It isn't useful to give another order since the pointer is already at the end of the file, and that it would anyway come back at the end of the file before to begin to write in case it was elsewhere: that's the 'a' mode characteristic. So, even if the pointer would be positionned again at the beginning of the file by a f.seek(0,0), the writing would be done at the end.

;

In case the test if 'readfalseloop2' in f.read() gives False, the pointer must be moved by f.seek(0,0) to the very beginning of the file for the new following reading of the entire file's content.

.

Warning: I don't know what could happen in case the file is written in utf-8, because in utf-8 the characters are not represented by the same length of bytes, it depends on the character. In my opinion, it should work correctly even with utf-8

.


EDIT

I found a clearer and shorter code:

from time import sleep

with open(WebPath + SmokeTest,'r+') as f:
    while not 'readfalseloop2' in f.read():
        print '~',
        f.seek(0,0)
        sleep(2)

    f.seek(0,1)
    f.write('\n<font color= "#347C2C">readfalseloop2</font><br />')
    print 'True'

Or

from time import sleep

with open(WebPath + SmokeTest,'r') as f, open(WebPath + SmokeTest,'a') as g:
    while not 'readfalseloop2' in f.read():
        print '~',
        f.seek(0,0)
        sleep(2)

    g.write('\n<font color= "#347C2C">readfalseloop2</font><br />')
    print 'True'

8 lines. Python is fantastic


The problem with your program is that are reading through the input file and writing to the output file. So if you find a single instance of the requested input your program will go into an infinite loop, as it will keep reading the last line, re-appending it to the output file, which is the input file, and then repeating.

I'd suggest a program like this:

import re

r = re.compile("readflaseloop2")
in_fn = WebPath + inputName
outf = open(in_fn + ".log","a")
count = 0
for line in open(in_fn):
    m = r.search(line)
    if m:
    if count==0:
            print True
        outf.write("<font color='#347C2C'>%s</font><br>\n" % m.group(0))
        outf.flush()
        count += 1
if count==0:
    print False


As vy32 noted, writing to the same file you're currently reading can be tricky (with the exact behaviour being OS dependent).

It also isn't entirely clear if the file you're reading is being updated live by another process. I'm going to assume that is the case, as simple line iteration would otherwise do the trick.

When reading a live file, the standard iterator isn't really what you want, as it will terminate as soon as it encounters an EOF marker. To monitor a live file, you either need to periodically poll it for new data, or else set up one of the OS-specific notification mechanisms that lets you know when new data is available.

There are some good answers to that question over here: How do I watch a file for changes?

Writing back to the same file is still going to be a potential problem though, especially if another process has it open for writing (even if you get the concurrent access to work, it will be tricky to get the monitoring program to ignore its own writes without risking missing writes from the application being monitored).

Example of using the file line iterator with collections.deque to remember context information while still benefiting from all the I/O optimisations built into the line iterator:

context = deque(maxlen=10) # Remember most recent 10 lines
for line in f:
    # Process the current line
    context.append(line)
0

精彩评论

暂无评论...
验证码 换一张
取 消