【问题标题】:TCL - catching the previous line and compareTCL - 捕捉上一行并比较
【发布时间】:2016-01-26 15:51:21
【问题描述】:

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

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

脚本有两个问题。一种是如果接口只有“snmp trap mac-notification change removed”行,脚本会跳过该块并转到下一个接口,直到找到具有三个命令(接口,添加snmp和删除snmp)的块或当不有两个 snmp 命令。另一个问题是,当最后一行“interface 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”命令来实现这一点是不合适的,但我没有找到另一种方法来做到这一点。如何修复所有错误?

谢谢。

【问题讨论】:

    标签: tcl


    【解决方案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"
        }
    }
    

    文档:chandictforeachifopenputssetsplitstring

    【讨论】:

    • 感谢 Peter Lewerin 先生。正是我需要的。像魅力一样工作!
    【解决方案2】:

    如果您一直想要相同的两行,那么您可以只查找 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
    

    【讨论】:

    • 感谢@wolfhammer 的回答,但这样我会重复我拥有的数据。我只需要捕获不包含两个 snmp 命令或只有一个命令的接口的块。
    猜你喜欢
    • 2015-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-22
    • 1970-01-01
    • 2014-12-27
    • 1970-01-01
    相关资源
    最近更新 更多