Danilo Braga
Danilo Braga

Reputation: 63

Making a simple output based on criterias that are not on the same line using tcl

I have a lot of files like below and I need to make a simple output based on criterias that are not on the same line.

file.txt

...
interface FastEthernet0/7 
switchport access vlan 10
switchport mode access
switchport nonegotiate
speed 100
duplex full
srr-queue bandwidth share 10 10 60 20
priority-queue out 
mls qos trust cos
snmp trap mac-notification change added
snmp trap mac-notification change removed
auto qos voip trust 
spanning-tree portfast
!
interface FastEthernet0/8
description WORKSTATION
switchport access vlan 20
switchport mode access
switchport nonegotiate
switchport voice vlan 10
srr-queue bandwidth share 10 10 60 20
priority-queue out 
authentication event fail action next-method
authentication event server dead action reinitialize vlan 20
authentication event server dead action authorize voice
authentication event server alive action reinitialize 
authentication host-mode multi-domain
authentication order dot1x mab
authentication violation restrict
authentication port-control auto
mab
mls qos trust device cisco-phone
mls qos trust cos
snmp trap mac-notification change added
snmp trap mac-notification change removed
dot1x pae authenticator
dot1x timeout tx-period 5
auto qos voip cisco-phone 
spanning-tree portfast
service-policy input AutoQoS-Police-CiscoPhone
ip dhcp snooping limit rate 10
ip dhcp snooping trust
!
interface FastEthernet0/9
description *** SERVER ***
switchport access vlan 20
switchport mode access
switchport nonegotiate
switchport voice vlan 10
srr-queue bandwidth share 10 10 60 20
priority-queue out 
mls qos trust device cisco-phone
mls qos trust cos
snmp trap mac-notification change added
snmp trap mac-notification change removed
auto qos voip cisco-phone 
spanning-tree portfast
service-policy input AutoQoS-Police-CiscoPhone
ip dhcp snooping limit rate 10
ip dhcp snooping trust
!
...

The bundle need to be between "interface" till "!". Inside this bundle, if I have the line "authentication port-control auto", the output will be:

FastEthernet0/8,WORKSTATION,DOT1X-OK

if not, will be:

FastEthernet0/9,*** SERVER ***,DOT1X-NOK

if I don't have a line with "description" and "authentication port-control auto" , like the bundle "interface FastEthernet0/7", the output will be:

FastEthernet0/7,null,DOT1X-NOK

I tried a lot of things, but none of my tries works. Any idea to make this thing using tcl?

Upvotes: 0

Views: 90

Answers (2)

Peter Lewerin
Peter Lewerin

Reputation: 13252

If a data file can be reinvented as a Tcl script, it is often useful to do so.

set data {{} null DOT1X-NOK}

proc interface slot {
    global data
    lset data 0 $slot
}

proc authentication args {
    global data
    if {[join $args] eq "port-control auto"} {
        lset data 2 DOT1X-OK
    }
}

proc description args {
    global data
    lset data 1 [join $args]
}

proc ! {} {
    global data
    puts [join $data ,]
    set data {{} null DOT1X-NOK}
    return
}

proc unknown args {}

source file.txt

Those lines that begin with a keyword that we are interested in get a corresponding command procedure that stores the “arguments” on the line. Those lines/keywords that we aren’t interested in are hidden by the no-op unknown procedure. As long as there aren’t any keywords that already have a Tcl definition in the file.txt file, we can now execute it as a source file. It is easy to extend this later, if desired, just by writing new command procedures to recognize more keywords.

Documentation: eq operator, global, if, join, lset, proc, puts, return, set, source, unknown

Upvotes: 1

Dinesh
Dinesh

Reputation: 16428

set interfaces [regexp -all -inline {interface.*?!} $input]
foreach interface $interfaces {
    set slot_info [regexp -line -inline {interface\s+(.*)} $interface]
    if {[llength $slot_info]==2} {
        set slot [lindex $slot_info 1]
    } else {
        set slot NA
    }
    set desc_info [regexp -line -inline {description\s+(.*)} $interface]
    if {[llength $desc_info]==2} {
        set desc [lindex $desc_info 1]
    } else {
        set desc null
    }
    if {[string first "authentication port-control auto" $interface]!=-1} {
        set dot1x "DOT1X-OK"
    } else {
        set dot1x "DOT1X-NOK"
    }
    puts "$slot,$desc,$dot1x"
}

Output :

FastEthernet0/7 ,null,DOT1X-NOK
FastEthernet0/8,WORKSTATION,DOT1X-OK
FastEthernet0/9,*** SERVER ***,DOT1X-NOK

Upvotes: 0

Related Questions