Наиболее упрощенная форма следующего регулярного выражения / Извлечение всех значений из вывода nvidia-smi
Я пытаюсь проанализировать очень большую текстовую строку в Python, содержащую выходные данные nvidia-smi, но я действительно хочу тратить больше времени на анализ данных, чем на работу над своими навыками регулярного выражения. Я получил следующее регулярное выражение, но в некоторых строках это занимает вечность (это может быть вариация входных данных в некоторых строках), но я подумал, что, возможно, мой шаблон регулярного выражения также очень требует больших вычислений.
extracted_line1 = r'[=]*[+][=]*[+][=]*\|\n\|(\s+(.*?)\|)+\n\|(\s+(.*?)\|)(\s+(.*?)\|)(\s+(.*?)\|)\n\|'
Этот шаблон соответствует третьей строке в таблице.
Этот внизу ⬇️
===============================+======================+======================|
| 0 GeForce GTX 1080 On | 00000000:04:00.0 Off | N/A |
| 27% 20C P8 6W / 180W | 2MiB / 8119MiB | 0% E. Process |
| | | N/A |
Он работает для большинства строк, но в некоторых строках зависает случайным образом. Какой была бы более упрощенная версия этого выражения регулярного выражения? Или, может быть, лучше спросить, как лучше всего получить каждое из значений в этой таблице для каждой строки (соответствующие показатели для каждого графического процессора)?
Здесь усеченная строка ввода 👇
... bunch of text
nvidia-smi:
Tue Jun 8 15:00:02 2021
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 460.80 Driver Version: 460.80 CUDA Version: 11.2 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|===============================+======================+======================|
| 0 GeForce GTX 1080 On | 00000000:04:00.0 Off | N/A |
| 27% 20C P8 6W / 180W | 2MiB / 8119MiB | 0% E. Process |
| | | N/A |
+-------------------------------+----------------------+----------------------+
| 1 GeForce GTX 1080 On | 00000000:05:00.0 Off | N/A |
| 27% 23C P8 6W / 180W | 2MiB / 8119MiB | 0% E. Process |
| | | N/A |
+-------------------------------+----------------------+----------------------+
... bunch of text
PS Я пытаюсь извлечь следующие значения
gpu_index = [processed result of regex output here]
gpu_model_name = [processed result of regex output here]
persistance_mode = [processed result of regex output here]
bus_id = [processed result of regex output here]
display_active = [processed result of regex output here]
volatile_ecc = [processed result of regex output here]
fan = [processed result of regex output here]
temperature = [processed result of regex output here]
perf = [processed result of regex output here]
power_usage = [processed result of regex output here]
max_power = [processed result of regex output here]
memory_usage = [processed result of regex output here]
available_mem = [processed result of regex output here]
gpu_utilization = [processed result of regex output here]
compute_mode = [processed result of regex output here]
multiple_instance_gpu_mode = [processed result of regex output here]
1 ответ
Я предлагаю другую схему, более экономичную для ресурсов вашего компьютера.
Шаблон
(\d+%)\s+(\d+C)\s+(\w\d)\s+(\d+W)\s+\/\s+(\d+W)\s+\|\s+(\d+MiB)\s+\/\s+(\d+MiB)\s+\|\s+(\d+\%)\s+(.*?)\s+\|
Прежде всего, я избавился от всего исходного шаблона поиска
=
или
+
chars, потому что регулярное выражение знает, как найти то, что вы ему указали. Никаких вспомогательных ручек не требуется.
Затем я обнаружил, что вам нужно только удерживать английские символы
\w
, цифры
\d
и пробелы
\s
и поэтому весь шаблон было довольно легко написать.
Объяснение
Я строю всю группу совпадений по шаблону за группой, пока не достигну окончательного результата. Обратите внимание, что каждое объяснение действительно только для последней группы совпадений, т.е.
(some ReGex expresion in parantesis)
(\d+%)
будет соответствовать любому количеству цифр, за которым следует
(\d+%)\s+(\d+C)
будет соответствовать любому количеству цифр после неизвестного количества пробелов, за которым следует буква
C
(\d+%)\s+(\d+C)\s+(\w\d)
будет соответствовать любому одиночному символу, за которым следует любая одиночная цифра
(\d+%)\s+(\d+C)\s+(\w\d)\s+(\d+W)
будет соответствовать любому количеству цифр после неизвестного количества пробелов, за которым следует один символ
(\d+%)\s+(\d+C)\s+(\w\d)\s+(\d+W)\s+\/\s+(\d+W)
зная, что там должны быть некоторые пробелы, затем и некоторые другие пробелы, это выражение будет соответствовать любому количеству цифр, за которыми следует
W
(\d+%)\s+(\d+C)\s+(\w\d)\s+(\d+W)\s+\/\s+(\d+W)\s+\|\s+(\d+MiB)
зная, что там должны быть некоторые пробелы, затем и некоторые другие пробелы, это выражение будет соответствовать любому количеству цифр, за которыми следует
(\d+%)\s+(\d+C)\s+(\w\d)\s+(\d+W)\s+\/\s+(\d+W)\s+\|\s+(\d+MiB)\s+\/\s+(\d+MiB)
зная, что там должны быть пробелы, тогда
/
и некоторые другие пробелы, это выражение будет соответствовать любому количеству цифр, за которыми следует
MiB
(\d+%)\s+(\d+C)\s+(\w\d)\s+(\d+W)\s+\/\s+(\d+W)\s+\|\s+(\d+MiB)\s+\/\s+(\d+MiB)\s+\|\s+(\d+\%)
зная, что там должны быть некоторые пробелы, затем и некоторые другие пробелы, это выражение будет соответствовать любому количеству цифр, за которыми следует
%
Последний бит
(\d+%)\s+(\d+C)\s+(\w\d)\s+(\d+W)\s+\/\s+(\d+W)\s+\|\s+(\d+MiB)\s+\/\s+(\d+MiB)\s+\|\s+(\d+\%)\s+(.*?)\s+\|
зная, что там должны быть некоторые пробелы, это выражение будет соответствовать любому количеству любых символов, пока не достигнет некоторого неизвестного количества пробелов, за которым следует
|
Наконец, рассматриваются следующие переменные:
gpu_index = not implemented
gpu_model_name = not implemented
persistance_mode = not implemented
bus_id = not implemented
display_active = not implemented
volatile_ecc = not implemented
fan = (\d+%)
temperature = (\d+C)
perf = (\w\d)
power_usage = (\d+W)
max_power = (\d+W)
memory_usage = (\d+MiB)
available_mem = (\d+MiB)
gpu_utilization = (\d+\%)
compute_mode = (.*?)
multiple_instance_gpu_mode = not implemented