Читайте текстовый файл построчно и сохраняйте переменные в соответствии с определенным шаблоном в Python - PullRequest
0 голосов
/ 29 августа 2018

У нас есть большой файл журнала, содержащий следующие две строки:

00 LOG     |   Cycles Run:  120001
00 LOG     ! Virtual: Max> ?????????? bytes (?.???? gb), Current> 640733184 bytes (?.???? gb).

00 LOG     ! Virtual: Max> 1082470400 bytes (?.???? gb), Current> ????????? bytes (?.???? gb).

00 LOG     ! Actual: Max> ????????? bytes (?.???? gb), Current> 472154112 bytes (?.???? gb).

00 LOG     ! Actual: Max> 861736960 bytes (?.???? gb), Current> ????????? bytes (?.???? gb).

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

например.

00 LOG     |   Cycles Run:  120001

Мы хотим выбрать 120001 и сохранить в переменной скажем cycle.

С другой стороны, мы анализируем эти строки:

00 LOG     ! Virtual: Max> ?????????? bytes (?.???? gb), Current> 640733184 bytes (?.???? gb).

00 LOG     ! Virtual: Max> 1082470400 bytes (?.???? gb), Current> ????????? bytes (?.???? gb).

00 LOG     ! Actual: Max> ????????? bytes (?.???? gb), Current> 472154112 bytes (?.???? gb).

00 LOG     ! Actual: Max> 861736960 bytes (?.???? gb), Current> ????????? bytes (?.???? gb).

Символы, отмеченные ?, могут быть любыми цифрами.

Мы хотим хранить vairables следующим образом:

640733184 в вари virtual_cur

1082470400 в вари virtual_max

472154112 в вари actual_cur

861736960 в вари actual_max

Написал фрагмент в Python 3.6, но печатает пустой список:

import re

filename = "test.txt"
with open(filename) as fp:  
   line = fp.readline()
   while line:
       cycle_num = re.findall(r'00 LOG     |   Cycles Run:  (.*?)',line,re.DOTALL)
       line = fp.readline()

print (cycle_num[0])

ПРИМЕЧАНИЕ: я хочу выбрать каждое значение в отдельных переменных и использовать его позже. Нужно установить 5 шаблонов по одному, выбрать значение, если оно совпадает любой конкретный шаблон и поместить его в соответствующую переменную.

Не уверен насчет подстановочного знака для второго шаблона.

Пожалуйста, предложите нам способ сделать это эффективно.

Ответы [ 3 ]

0 голосов
/ 29 августа 2018

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

import re
with open('test.txt','r') as f:
    for line in f:
        if re.search(r'Cycles',line):
            m=re.findall(r'\d+$',line)
        else:
            m=re.findall(r'Current>  (\d+)',line)
        print(m)
0 голосов
/ 29 августа 2018

с регулярным выражением

(?:(?:Cycles Run:[ \t]+)|(?:Current>[ \t]+))(\d+)

Демо

Вы можете сделать что-то вроде этого:

import re
pat=re.compile(r'(?:(?:Cycles Run:[ \t]+)|(?:Current>[ \t]+))(\d+)')
with open('test.txt','r') as f:   
    for line_num, line in enumerate(f):
        m=pat.search(line)
        if m:
            print(line_num, m.group(0))
0 голосов
/ 29 августа 2018

Здесь вы можете использовать чередование с двумя взглядами:

(?<=Cycles Run:  )\d+|(?<= Current>  )\d+

Regex demo здесь .


Пример Python:

import re
text = '''
00 LOG     |   Cycles Run:  120001
00 LOG     !   Virtual: Max> 1082470400 bytes (1.0081 gb), Current>  640733184 bytes (0.5967 gb)
'''

pattern = re.compile(r'(?<=Cycles Run:  )\d+|(?<= Current>  )\d+')
matches = re.findall(pattern,text)
num_cycle = matches[0]
current = matches[1]

print(num_cycle,current)

Печать:

120001 640733184

Поскольку вы повторяете процесс в цикле, рекомендуется использовать re.compile для компиляции шаблона только один раз перед циклом.

...