Регулярное выражение для получения номера версии микропрограммы из Cisco IOS `show version`

Мне нужна помощь в получении версии микропрограммы из вывода команды Cisco "show version"

Ниже приведена первая строка выходных данных версии show (где «12.4(21a)JA1» — версия встроенного ПО):

Cisco IOS Software, C1240 Software (C1240-K9W7-M), Version 12.4(21a)JA1, RELEASE
SOFTWARE (fc1)

Приведенный ниже код дает мне ошибку: не удалось скомпилировать шаблон регулярного выражения: недопустимый операнд квантификатора

expect "*#" {send "show version\n"}
expect -re "(?<=Version/s)(.*)(?=/sRELEASE)" {set var1 $expect_out(1,string)}
puts "Firmware Version: $var1"

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


person atomicluis    schedule 29.07.2012    source источник


Ответы (2)


Ваша проблема двояка. Во-первых, Expect не поддерживает ограничения просмотра назад (ну, не в обычных сборках). Во-вторых, ваше регулярное выражение смешивает используемые косые черты. Всегда полезно помещать регулярные выражения в фигурные скобки в Tcl и (в расширении) Expect. Я также рекомендую использовать многострочную версию expect (как показано ниже), когда все становится длиннее, так как это намного проще для глаз.

expect "*#" {send "show version\n"}
expect {
    -re {Version\s+(.*),\s+RELEASE} {
        set firmwareVersion $expect_out(1,string)
    }
}
puts "Firmware Version: $firmwareVersion"

Единственным недостатком помещения фигурных скобок является то, что SO неправильно их форматирует. Мы можем пережить такие трудности, я думаю…

person Donal Fellows    schedule 29.07.2012
comment
Возможно перестроить Tcl для использования PCRE в качестве движка RE — хотя на данный момент это не поддерживается, и даже ничего из того, что есть в основном дереве исходного кода Tcl (я знаю о коммерческом эксперименте ) — и если это будет сделано, то Expect может работать правильно. А может и нет; Expect довольно сильно управляет движком RE, используя множество малоизвестных функций. - person Donal Fellows; 30.07.2012
comment
+1 Я бы сказал, что, поскольку он взаимодействует с Cisco, ему также нужно искать подсказку в ожидании ... поэтому моя рекомендация - person This; 30.07.2012
comment
Кстати, ваше регулярное выражение должно быть ограничено ?, потому что .* слишком жадно и захватывает гораздо больше, чем необходимо... Я бы использовал (\d.+?), - person This; 30.07.2012
comment
@Mike Переход к нежадным не помогает так сильно, как вы думаете; Expect применяет шаблон по мере поступления данных, поэтому нет никакой реальной пользы в том, чтобы говорить о том, что пространство совпадения должно быть небольшим. (Было бы полезно, если бы в потоке данных было много использований «Version» или если бы было два слова «RELEASE», но это маловероятно.) Лучше было бы использовать (\S*), так как вероятность того, что это совпадет с длинным кусок текста, но на самом деле это не критично, так как пространство совпадения также ограничено ранее сопоставленным приглашением. - person Donal Fellows; 30.07.2012
comment
И я предполагаю, что он может найти подсказку; Я вообще не знаю устройства Cisco (кроме репутации). - person Donal Fellows; 30.07.2012
comment
У меня есть tcl8.5 и я ожидаю 5.44.1.15... когда я использую ваше регулярное выражение, оно слишком жадное и соответствует нескольким строкам текста. Если я использую предложение в своем комментарии выше, оно строго соответствует номеру версии IOS. Я признаю, что имею преимущество протестировать это по желанию на нашей инфраструктуре. - person This; 30.07.2012

Исходный:

expect "*#" {send "show version\n"}
expect -re "(?<=Version/s)(.*)(?=/sRELEASE)" {set var1 $expect_out(1,string)}
puts "Firmware Version: $var1"

Во-первых, как упомянул Донал, expect не поддерживает регулярные выражения просмотра назад...

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

Рекомендуется:

expect "*#" {send "show version\n"}
expect "*#" {send "# something else here"}
regexp {Version\s(\d.+?),\sRELEASE\sSOFTWARE} $expect_out(buffer) matched var1
puts "Firmware Version: $var1"
person This    schedule 29.07.2012
comment
Сопоставить строку, которая находится на одной строке, не так уж сложно. Это многострочные матчи, которые могут стать… захватывающими… - person Donal Fellows; 30.07.2012
comment
но для вывода Cisco show version требуется многострочное сопоставление, чтобы получить как номер версии, и подсказку - person This; 30.07.2012