2011-02-01 2 views
3

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

Все, что я хочу сделать, это цикл поиска строки до тех пор, пока строка не будет найдена. Я ищу файл журнала для строки, которая появляется, когда возникает условие, например. когда строка "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 

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

У меня не было успеха с какой-либо петлевой конструкцией и ДА Я просмотрел документы python, обыскал этот сайт и ubuntu forum.

+2

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

+0

Да, это именно то, что я пытаюсь сделать. – Surfdork

+0

Я еще не нашел рабочий пример в Интернете, как это сделать, не используя стороннюю библиотеку, которую мне не удалось сделать в Sikuli – Surfdork

ответ

1

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

Я хотел бы предложить программу, как это:

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 
+1

. Почему r.search (строка) вместо r.search (content_of_file)? – eyquem

+0

Потому что я хочу видеть каждую строку, которая соответствует. С помощью r.search (content_of_file) вам необходимо сращить обработанный результат с выводом, который вы не обработали, что значительно увеличит использование памяти, если вы хотите получить следующее совпадение. Но, видимо, это не то, чего хотел создатель. – vy32

1

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

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

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

Есть несколько хороших ответов на этот вопрос здесь: How do I watch a file for changes?

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

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

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

Хорошая информация hiowever Я ищу конкретный контент, поэтому параметры линии не будут удовлетворять мои потребности. – Surfdork

+0

Если вам нужно сохранить какой-то контекст, вы можете довольно легко использовать deque с «maxlen», чтобы запомнить небольшое количество предыдущих строк. Это дает вам преимущество кэширования, встроенного в итератор файла, без потери необходимого контекста. – ncoghlan

4

Хорошего код Эндрю. Мне не сообщили о существовании для/else.

Но умерить активность процессов машины, можно избежать повторного открытия и закрытия файла, и предпочтительно, чтобы охладиться частоту проверки ИМО

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

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

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

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

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

;

В случае тест если «readfalseloop2» в f.read() дает ложных, указатель должен быть перемещен на 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 линий. Python - это фантастика

+0

Это определенно лучше в том смысле, что файл не открывается и не закрывается, но чтение всего файла сразу может быть проблемой, если файл большой, а еще +1. –

+0

@ Андри Да, действительно. Наличие большого файла для обработки все еще вызывает ту же самую раздражающую специфическую проблему. Если он читается за один раз, он тяжелый для памяти; если он читается по одной строке за раз, он может быть длинным. У меня нет универсального решения. В данном случае user577229 хочет обработать файл журнала, который может быть не слишком большим. – eyquem

+0

Добавление одинарных кавычек к именам приводит к сбою кода, jython не знает, что с ним делать. Я не имел никакого успеха в создании этих функций-фрагментов – Surfdork

Смежные вопросы