TCL - 赶上前一行并进行比较

时间:2016-01-26 15:51:22

标签: tcl

我有一个包含内容的文件。

file.txt

interface FastEthernet0/20
 snmp trap mac-notification change added
interface FastEthernet0/21
 snmp trap mac-notification change added
 snmp trap mac-notification change removed
interface FastEthernet0/22
 snmp trap mac-notification change removed
interface FastEthernet0/23
 snmp trap mac-notification change added
 snmp trap mac-notification change removed
interface FastEthernet0/24
 snmp trap mac-notification change added
 snmp trap mac-notification change removed
interface GigabitEthernet0/1
interface GigabitEthernet0/2

我做了一个脚本来读取这个文件,如果接口没有两行“snmp trap mac-notification change added”和“snmp trap mac-notification change removed”,我需要把这两个命令分别在接口下面。

期待输出:

conf t
interface FastEthernet0/20
snmp trap mac-notification change added
snmp trap mac-notification change removed
conf t
interface FastEthernet0/21
snmp trap mac-notification change added
snmp trap mac-notification change removed
conf t
interface FastEthernet0/22
snmp trap mac-notification change added
snmp trap mac-notification change removed
conf t
interface GigabitEthernet0/1
snmp trap mac-notification change added
snmp trap mac-notification change removed
conf t
interface GigabitEthernet0/2
snmp trap mac-notification change added
snmp trap mac-notification change removed

该脚本有2个问题。一种是如果接口只有“snmp trap mac-notification change removed”,脚本跳过该块并转到下一个接口,直到找到带有三个命令的块(接口,snmp被添加并且snmp被移除)或者当没有有两个snmp命令。另一个问题是,当最后一行“接口GigabitEthernet0 / 2”没有snmp命令时,脚本也会跳过它。

这是剧本。

    set intf {}
    set PR {}
    set PPR {}
    set PPRfullintf {}
    set PPRintf {}
    set PRfullintf {}
    set PRintf {}
    set 4 {}
    set P4 {}
    set f [open "file.txt" r]
    foreach a [split [read -nonewline $f] \n] {
        set 1 [lindex $a 1]
        set 0 [lindex $a 0 ]
        set 4 [lindex $a 4 ]

        if { [regexp {^Fa|^Gi} $1] } { set intf1 "interface $1" }

        if { $4 != "added" && $4 != "removed" && $P4 == "added" && $PR == "interface" } {
            puts "conf t\r"
            puts "$PRfullintf\r"
            puts "snmp trap mac-notification change added\r"
            puts "snmp trap mac-notification change removed\r"
        }

        if { $0 == "interface" && $PR == "interface" } {
            puts "conf t\r"
            puts "$PRfullintf\r"
            puts "snmp trap mac-notification change added\r"
            puts "snmp trap mac-notification change removed\r"          
        }
        set P4 $4
        if { $4 == "added" || $4 == "removed" } { set P4 $4 }
        set PR $0
        set PRfullintf $intf1
        set PRintf $1
    }
    close $f

意外输出:

 conf t
 interface FastEthernet0/20
 snmp trap mac-notification change added
 snmp trap mac-notification change removed
 conf t
 interface FastEthernet0/21
 snmp trap mac-notification change added
 snmp trap mac-notification change removed
 conf t
 interface GigabitEthernet0/1
 snmp trap mac-notification change added
 snmp trap mac-notification change removed

我认为尝试使用命令“foreach”来做到这一点是不合适的,但我没有找到另一种方法来做到这一点。我该如何解决所有错误?

感谢。

2 个答案:

答案 0 :(得分:1)

如果在两次传递中完成,这种文本解析会容易得多。以下代码首先在字典中注册“接口”行,然后计算“接口”行(0,1或2)后面的行。我假设如果后面有两行,一行是“添加”行,另一行是“删除”行。

在第二遍中,遍历字典并打印0和1计数项目。

set f [open file.txt]
foreach line [split [string trim [chan read $f]] \n] {
    if {[string match interface* $line]} {
        set key $line
        dict set interfaces $key 0
    } else {
        dict incr interfaces $key
    }
}
chan close $f

dict for {key n} $interfaces {
    if {$n < 2} {
        puts "conf t"
        puts $key
        puts "snmp trap mac-notification change added"
        puts "snmp trap mac-notification change removed"
    }
}

文档:chandictforeachifopenputsset,{{3 },split

答案 1 :(得分:0)

如果你想要一直两行,那么你可以只查找interface行并跳过其余部分。

set data {
interface FastEthernet0/20
 snmp trap mac-notification change added
interface FastEthernet0/21
 snmp trap mac-notification change added
 snmp trap mac-notification change removed
interface FastEthernet0/22
 snmp trap mac-notification change removed
interface FastEthernet0/23
 snmp trap mac-notification change added
 snmp trap mac-notification change removed
interface FastEthernet0/24
 snmp trap mac-notification change added
 snmp trap mac-notification change removed
interface GigabitEthernet0/1
interface GigabitEthernet0/2
}

set data [split $data "\n"]
set new_data ""

foreach {line} $data {
  if {[string first "interface" $line] != -1} {
    # Found an interface. Add to new_data
    append new_data "conf t\n$line\n"
    append new_data "snmp trap mac-notification change added\n"
    append new_data "snmp trap mac-notification change removed\n"
  }
}

puts $new_data