exp_continue如何工作? exp_continue的问题

时间:2015-06-29 05:40:32

标签: regex tcl expect

我正在尝试从我的cisco设备中捕获库存数据。我虽然很容易,但我遇到了问题。

而不是匹配和整个“set”数据(来自Name。+ SN是一组)我以为我会分割我的maches并使用exp_continue来使我的Regex更具可读性。

如果你看下面的话,当它收集“名字”时似乎exp_continue是超级贪婪的

数据集:

HOSTNAME#sho inventory
NAME: "WS-C6506-E", DESCR: "Cisco Systems, Inc. Catalyst 6500 6-slot Chassis System"
PID: WS-C6506-E        ,                     VID: V03, SN: SAL1547VW8B

NAME: "WS-C6K-VTT-E 1", DESCR: "VTT-E FRU 1"
PID: WS-C6K-VTT-E      ,                     VID:    , SN: SMT1541B899

NAME: "WS-C6K-VTT-E 2", DESCR: "VTT-E FRU 2"
PID: WS-C6K-VTT-E      ,                     VID:    , SN: SMT1541B910

NAME: "WS-C6K-VTT-E 3", DESCR: "VTT-E FRU 3"
PID: WS-C6K-VTT-E      ,                     VID:    , SN: SMT1541B903

NAME: "CLK-7600 1", DESCR: "OSR-7600 Clock FRU 1"
PID: CLK-7600          ,                     VID:    , SN: SMT1544A575

NAME: "CLK-7600 2", DESCR: "OSR-7600 Clock FRU 2"
PID: CLK-7600          ,                     VID:    , SN: SMT1544A575

NAME: "3", DESCR: "WS-X6724-SFP CEF720 24 port 1000mb SFP Rev. 5.1"
PID: WS-X6724-SFP      ,                     VID: V08, SN: SAL160214AY

NAME: "WS-F6700-CFC Centralized Forwarding Card sub-module of 3", DESCR: "WS-F6700-CFC Centralized Forwarding Card Rev. 4.1"
PID: WS-F6700-CFC      ,                     VID: V06, SN: SAL160317SU

NAME: "4", DESCR: "WS-X6324-100FX-MM 24 port 100FX Multi mode Rev. 3.6"
PID: WS-X6324-100FX-MM ,                     VID:    , SN: SAL091805J9

NAME: "5", DESCR: "WS-SUP720-3B 2 ports Supervisor Engine 720 Rev. 5.6"
PID: WS-SUP720-3B      ,                     VID: V05, SN: SAL1226UYLK

NAME: "msfc sub-module of 5", DESCR: "WS-SUP720 MSFC3 Daughterboard Rev. 3.1"
PID: WS-SUP720         ,                     VID:    , SN: SAL1226UXVD

NAME: "WS-F6K-PFC3B Policy Feature Card 3 sub-module of 5", DESCR: "WS-F6K-PFC3B Policy Feature Card 3 Rev. 2.3"
PID: WS-F6K-PFC3B      ,                     VID: V01, SN: SAL1225UQAQ

NAME: "6", DESCR: "WS-X6324-100FX-MM 24 port 100FX Multi mode Rev. 3.6"
PID: WS-X6324-100FX-MM ,                     VID:    , SN: SAL091805HU

NAME: "WS-C6506-E-FAN 1", DESCR: "Enhanced 6-slot Fan Tray 1"
PID: WS-C6506-E-FAN    ,                     VID: V03, SN: DCH1547004V

NAME: "PS 1 WS-CAC-3000W", DESCR: "AC power supply, 3000 watt 1"
PID: WS-CAC-3000W      ,                     VID: V02, SN: SNI1543AX19

NAME: "PS 2 WS-CAC-3000W", DESCR: "AC power supply, 3000 watt 2"
PID: WS-CAC-3000W      ,                     VID: V02, SN: SNI1543AX1F
HOSTNAME#

代码:

send "show inventory\r"
expect {
        -nocase -re {NAME: "([^\"]+)"} {
                set NAME $expect_out(1,string)
                puts "Name $NAME!!!!"
                exp_continue
        }
        -nocase -re {DESCR: "([^\"]+)"} {
                set DESCR $expect_out(1,string)
                puts "Des $DESCR!!!!"
                exp_continue
        }
        -nocase -re {PID:([^,]+)} {
                set PID $expect_out(1,string)
                puts "PID $PID!!!!"
                exp_continue
        }
        -nocase -re {VID:([^,]+)} {
                set VID $expect_out(1,string)
                puts "VID $VID!!!!"
                exp_continue
        }
        -nocase -re {SN: ([^\r]+)} {
                set SN $expect_out(1,string)
                puts "SN $SN!!!!\n\n"
                lappend info "$hostname,$NAME,$DESCR,$PID,$VID,$SN"
                exp_continue
        }
        "#"
}
 foreach I $info {
   puts "$I"
  }

这是输出

Name WS-C6506-E!!!!
Name WS-C6K-VTT-E 1!!!!
Name WS-C6K-VTT-E 2!!!!
Name WS-C6K-VTT-E 3!!!!
Name CLK-7600 1!!!!
Name CLK-7600 2!!!!
Name 3!!!!
Name WS-F6700-CFC Centralized Forwarding Card sub-module of 3!!!!
Name 4!!!!
Name 5!!!!
Name msfc sub-module of 5!!!!
Name WS-F6K-PFC3B Policy Feature Card 3 sub-module of 5!!!!
Name 6!!!!
Name WS-C6506-E-FAN 1!!!!
Name PS 1 WS-CAC-3000W!!!!
Name PS 2 WS-CAC-3000W!!!!
Des AC power supply, 3000 watt 2!!!!
PID  WS-CAC-3000W      !!!!
VID  V02!!!!
SN SNI1543AX1F!!!!

HOSTNAME,AC power supply, 3000 watt 2, WS-CAC-3000W      , V02,SNI1543AX1F

2 个答案:

答案 0 :(得分:2)

由于始终会检查NAME匹配,因此您会看到此行为归因于exp_continue在此处被滥用。

而不是这样,您可以等到设备的提示。整个输出将在expect_out(buffer)中提供。然后应用regexp来提取所需的数据。

send "show inventory\r"
expect "HOSTNAME#"
set cmdResponse $expect_out(buffer); # Saving the buffer output to another variable
# 'inline' and 'all' flags will cause the all matches to be returned as list
set resultList [regexp -inline -all {NAME.*?"([^"]+)?.*?DESCR.*?"([^"]+)?.*?PID.*?\s(\S+).*?,.*?VID:\s+(.*)?,.*?SN:\s(.*)?\n} $cmdResponse ]

# Quoting the values with double quotes
foreach {whole_match name descr pid vid serialno} $resultList {
        puts "NAME = \"$name\", DESCR = \"$descr\", PID = \"$pid\", VID = \"$vid\", SN = \"$serialno\""
}

输出

NAME = "WS-C6506-E", DESCR = "Cisco Systems, Inc. Catalyst 6500 6-slot Chassis System", PID = "WS-C6506-E", VID = "V03", SN = "SAL1547VW8B"
NAME = "WS-C6K-VTT-E 1", DESCR = "VTT-E FRU 1", PID = "WS-C6K-VTT-E", VID = "", SN = "SMT1541B899"
NAME = "WS-C6K-VTT-E 2", DESCR = "VTT-E FRU 2", PID = "WS-C6K-VTT-E", VID = "", SN = "SMT1541B910"
NAME = "WS-C6K-VTT-E 3", DESCR = "VTT-E FRU 3", PID = "WS-C6K-VTT-E", VID = "", SN = "SMT1541B903"
NAME = "CLK-7600 1", DESCR = "OSR-7600 Clock FRU 1", PID = "CLK-7600", VID = "", SN = "SMT1544A575"
NAME = "CLK-7600 2", DESCR = "OSR-7600 Clock FRU 2", PID = "CLK-7600", VID = "", SN = "SMT1544A575"
NAME = "3", DESCR = "WS-X6724-SFP CEF720 24 port 1000mb SFP Rev. 5.1", PID = "WS-X6724-SFP", VID = "V08", SN = "SAL160214AY"
NAME = "WS-F6700-CFC Centralized Forwarding Card sub-module of 3", DESCR = "WS-F6700-CFC Centralized Forwarding Card Rev. 4.1", PID = "WS-F6700-CFC", VID = "V06", SN = "SAL160317SU"
NAME = "4", DESCR = "WS-X6324-100FX-MM 24 port 100FX Multi mode Rev. 3.6", PID = "WS-X6324-100FX-MM", VID = "", SN = "SAL091805J9"
NAME = "5", DESCR = "WS-SUP720-3B 2 ports Supervisor Engine 720 Rev. 5.6", PID = "WS-SUP720-3B", VID = "V05", SN = "SAL1226UYLK"
NAME = "msfc sub-module of 5", DESCR = "WS-SUP720 MSFC3 Daughterboard Rev. 3.1", PID = "WS-SUP720", VID = "", SN = "SAL1226UXVD"
NAME = "WS-F6K-PFC3B Policy Feature Card 3 sub-module of 5", DESCR = "WS-F6K-PFC3B Policy Feature Card 3 Rev. 2.3", PID = "WS-F6K-PFC3B", VID = "V01", SN = "SAL1225UQAQ"
NAME = "6", DESCR = "WS-X6324-100FX-MM 24 port 100FX Multi mode Rev. 3.6", PID = "WS-X6324-100FX-MM", VID = "", SN = "SAL091805HU"
NAME = "WS-C6506-E-FAN 1", DESCR = "Enhanced 6-slot Fan Tray 1", PID = "WS-C6506-E-FAN", VID = "V03", SN = "DCH1547004V"
NAME = "PS 1 WS-CAC-3000W", DESCR = "AC power supply, 3000 watt 1", PID = "WS-CAC-3000W", VID = "V02", SN = "SNI1543AX19"
NAME = "PS 2 WS-CAC-3000W", DESCR = "AC power supply, 3000 watt 2", PID = "WS-CAC-3000W", VID = "V02", SN = "SNI1543AX1F"

有些条目没有VID信息,也会在输出中显示为空字符串。

答案 1 :(得分:1)

您应该在一个正则表达式中包含所有关键字( NAME DESCR ,...)。例如:

$ cat foo.exp
log_user 0
spawn cat file
set info {}
expect {
    -re {NAME: "([^"]*)",\s*DESCR: "([^"]*)"\s+PID: (\S*)\s*,\s*VID:\
         (\S*)\s*,\s*SN: (\S*)} {
        set name $expect_out(1,string)
        set desc $expect_out(2,string)
        set pid  $expect_out(3,string)
        set vid  $expect_out(4,string)
        set sn   $expect_out(5,string)
        lappend info "$name | $desc | $pid | $vid | $sn"
        exp_continue
    }
}

foreach i $info {
    puts $i
}
$ cat file
NAME: "WS-C6K-VTT-E 1", DESCR: "VTT-E FRU 1"
PID: WS-C6K-VTT-E      ,                     VID:    , SN: SMT1541B899

NAME: "3", DESCR: "WS-X6724-SFP CEF720 24 port 1000mb SFP Rev. 5.1"
PID: WS-X6724-SFP      ,                     VID: V08, SN: SAL160214AY

NAME: "PS 2 WS-CAC-3000W", DESCR: "AC power supply, 3000 watt 2"
PID: WS-CAC-3000W      ,                     VID: V02, SN: SNI1543AX1F
$ expect foo.exp
WS-C6K-VTT-E 1 | VTT-E FRU 1 | WS-C6K-VTT-E |  | SMT1541B899
3 | WS-X6724-SFP CEF720 24 port 1000mb SFP Rev. 5.1 | WS-X6724-SFP | V08 | SAL160214AY
PS 2 WS-CAC-3000W | AC power supply, 3000 watt 2 | WS-CAC-3000W | V02 | SNI1543AX1F
$