Цикл поиска строки, пока строка не найдена python - PullRequest
3 голосов
/ 01 февраля 2011

Я думал, что это будет легко, после 3 часов поиска, проб и ошибок, кажется, что это не так просто.

Все, что я хочу сделать, - это цикл поиска строки, пока строка не будет найдена.Я ищу в файле журнала строку, которая появляется, когда возникает условие, например, когда в журнале появляется строка "function test 1", мне нужно найти ее, а затем выполнить другую функцию.

Найти ее не проблема,проблема в цикле, пока он не найден.

Это прекрасно находит:

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

Я хочу выполнить это, пока слово не будет найдено.В идеале я хотел бы встроить это в несколько функций, я не хочу отдельного определения на этом этапе.

Я не добился успеха с какой-либо циклической конструкцией, и ДА, я смотрел на документы по Python,искал этот сайт и форум Ubuntu .

Ответы [ 3 ]

4 голосов
/ 01 февраля 2011

Хороший код Андрей. Мне не сообщили о существовании возможности for / else .

Но, чтобы умерить активность процессов машины, можно избежать повторного открытия и закрытия файла, и предпочтительно снизить частоту проверки 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)

Этот код работает, я проверял. Но только если изменение выполняется с помощью другой программы. Когда я попытался изменить файл, вставив

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

цепочка вручную, Windows отказалась закрывать файл с изменением.

.

После f.read () указатель файла f должен быть повторно активирован, чтобы можно было написать

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

цепочка в конце содержимого файла.

Я не знаю, в чем состоит эта реактивация. Я только знаю, что если инструкция f.seek (0,1) не выполнена, процесс не может переключиться из режима чтения в режим записи.

f.seek (0,1) означает «перемещение 0 символов из вашей текущей позиции»; Бесполезно отдавать другой порядок, так как указатель уже находится в конце файла и что он все равно вернется в конец файла, прежде чем начать писать в случае, если он был где-то еще: это «a» характеристика режима. Таким образом, даже если указатель будет снова помещен в начале файла с помощью f.seek (0,0), запись будет выполнена в конце.

;

В случае проверки , если readfalseloop2 в f.read () дает False , указатель должен быть перемещен на f.seek (0,0) в самое начало файла для нового последующего чтения содержимого всего файла.

.

Предупреждение: я не знаю, что может произойти, если файл записан в utf-8, потому что в utf-8 символы не представлены одинаковой длиной в байтах, это зависит от символа. На мой взгляд, он должен работать правильно даже с utf-8

.


EDIT

Я нашел более понятный и короткий код:

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'

или

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 строк. Питон фантастический

1 голос
/ 01 февраля 2011

Как отмечал vy32, запись в тот же файл, который вы сейчас читаете, может быть сложной (с точным поведением, зависящим от ОС).

Также не совсем ясно, читается ли файл, который вы читаетеобновляется в реальном времени другим процессом.Я собираюсь предположить, что это так, так как в противном случае простая итерация строки справилась бы с задачей.

При чтении живого файла стандартный итератор не совсем то, что вам нужно, так как он завершится, как толькокак он встречает маркер EOF.Чтобы отслеживать оперативный файл, вам нужно либо периодически опрашивать его на предмет новых данных, либо настроить один из механизмов уведомлений, зависящих от ОС, который позволяет вам знать, когда появляются новые данные.

Есть несколько хороших ответовна этот вопрос здесь: Как посмотреть файл на предмет изменений?

Запись в тот же файл все еще будет потенциальной проблемой, особенно если другой процесс его откроетдля записи (даже если вы получаете одновременный доступ к работе, будет сложно заставить программу мониторинга игнорировать свои собственные записи, не рискуя пропустить записи из отслеживаемого приложения).

Пример использования строки файлаитератор с collection.deque для запоминания контекстной информации, в то же время извлекающий выгоду из всех оптимизаций ввода / вывода, встроенных в линейный итератор:

context = deque(maxlen=10) # Remember most recent 10 lines
for line in f:
    # Process the current line
    context.append(line)
1 голос
/ 01 февраля 2011

Проблема вашей программы в том, что вы читаете входной файл и записываете в выходной файл.Поэтому, если вы найдете один экземпляр запрошенного ввода, ваша программа перейдет в бесконечный цикл, так как будет продолжать читать последнюю строку, повторно добавлять ее в выходной файл, который является входным файлом, а затем повторять.*

Я бы предложил такую ​​программу:

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
...