我有一个包含内容的文件。
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”来做到这一点是不合适的,但我没有找到另一种方法来做到这一点。我该如何解决所有错误?
感谢。
答案 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"
}
}
答案 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