как получить значение из txt файла на строку выше поискового запроса. Python

есть батник, который получает информацию о установленных драйверах и пишет лог в текстовик pnputil.exe -e > "D:\drv.txt"

результат примерно такой:

Опубликованное имя :            
oem5.inf
Поставщик пакета драйвера:   Canon
Класс:                     Устройства обработки изображений
Дата разработки и версия драйвера :   
09/16/2010 11.3.0.1
Имя подписавшего :               Microsoft Windows Hardware Compatibility Publisher

нужно чтоб по этому текстовику производился поиск по ключевому слову (например "canon") и на выходе имелась информация на строчку выше (в данном случае "oem5.inf")

сделать поиск не сложно, а вот как выцепить строку сверху я хз (я ещё совсем новичок в питоне)

import os

os.system("d:\\drv.bat")

a = 'Canon'
file = open('D:\\drv.txt', 'r')
text = file.read()
if a in text:
    #тут мог быть ваш код

Ответы (2 шт):

Автор решения: GrAnd

Можно распарсить весь файл в список словарей. А дальше дело техники найти нужные словари по одному из полей и взять от них значение другого поля.

drivers = []      # здесь будут храниться словари с описанием драйверов, каждый словарь - один драйвер
with open('D:\\drv.txt', 'r') as f:
    drv = {}             # изначально словарь с описанием драйвера пустой
    line = f.readline()  # читаем строку
    while line:          # работаем пока очередная строка не будет пустой, что означает конец файла
        buf = line = line.strip()    # чистим строку от пробелов и переводов строк с обеих концов
        if buf and buf[-1] == ":":   # если последний символ - двоеточие, то продолжение на следующей строке
            line = f.readline().strip()     # читаем следующую строку (ибо она есть продолжение предыдущей)
            buf += line                     # и дописываем её к предыдущей (в буфер)
        if ":" in buf:     # если в буфере получилась строка вида "что-то : значение"
                           # то разбиваем её по двоеточию и добавляем в словарь как 'drv[что-то] = значение'  (предварительно почистив от пробелов с краёв)
            drv.update([map(lambda x: x.strip(), buf.split(":",1))])

        if not line and drv:     # если обнаружилась пустая строка (это разделитель между описаниями разных драйверов) и словарь с описанием не пустой
            drivers.append(drv)  # значит надо добавить текущий словарь с описанием в общий список
            drv = {}             # и начать собирать новое описание с пустого словаря

        line = f.readline()    # читаем следующую строку чтобы начать её анализ с начала следующей итерации цикла

what = "logitech"
# это просто цикл по всем элементам (которые словари) списка, 
# где если значение по ключу элемента соответствует критерию, 
# то достаётся значение по другому ключу и оно добавляется в выходной список
infs = [drv["Опубликованное имя"] for drv in drivers if what in drv["Поставщик пакета драйвера"].lower()]  
print(infs)

Пример содержимого словаря с описанием одного из драйверов:

{
 'Опубликованное имя': 'oem189.inf', 
 'Поставщик пакета драйвера': 'NVIDIA', 
 'Класс': 'Видеоадаптеры', 
 'Дата разработки и версия драйвера': '10/27/2017 23.21.13.8813',
 'Имя подписавшего': 'Microsoft Windows Hardware Compatibility Publisher'
}

Результат поиска установленных дров Logitech в моей системе.

['oem124.inf', 'oem125.inf', 'oem126.inf', 'oem147.inf', 'oem148.inf', 'oem149.inf']
→ Ссылка
Автор решения: Виктор Боровой

Спасибо за помощь

Целью проекта была переустановка драйвера принтера Canon, ибо каждый раз винда ставила свой драйвер и сканер переставал работать.

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

должно быть 3 inf файла, а у драйвера от винды всего 1

вот и пришлось писать этот скрипт, чтоб не переустанавливать каждый раз драйвер вручную

вот результат если кому интересно

import os
import time

os.system("pnputil.exe -e > D:\drv.txt")

drivers = []
with open('D:\\drv.txt', 'r') as f:
    drv = {}
    line = f.readline()
    while line:
        buf = line = line.strip()
        if buf and buf[-1] == ":":
            line = f.readline().strip()
            buf += line
        if ":" in buf:
            drv.update([map(lambda x: x.strip(), buf.split(":", 1))])

        if not line and drv:
            drivers.append(drv)
            drv = {}

        line = f.readline()

print("Поиск драйвера...")
time.sleep(3)
what = "canon"
infs = [drv["Опубликованное имя"] for drv in drivers if what in drv["Поставщик пакета драйвера"].lower()]
print("вот что мне удалось найти:")
print(infs)
time.sleep(1)
f = open('D:\\result.txt', 'w')
for index in infs:
    f.write(index + '\n')
f.close()

fl = open('D:\\result.txt', 'r')
S = fl.read()
fl.close()
print("Удаление старых драйверов...")
time.sleep(1)
os.system("pnputil.exe -f -d " + S)
print("ok")
print("Установка новых драйверов...")
time.sleep(1)
os.system("pnputil -i -a D:\\Driver\\*.inf")
print("ok")
print("ОТКЛЮЧИТЕ И ЗАНОВО ПОДКЛЮЧИТЕ USB КАБЕЛЬ ПРИНТЕРА")
os.system("pause")

Запускать нужно от имени администратора

→ Ссылка