我是编程和积极学习TCL以开发嵌入式系统的初学者。
我必须在当前目录中搜索只有.txt格式的文件,计算.txt文件中每个不同“Interface #nnnn”字符串的个案数,其中nnnn是4到32位最大十六进制数和出现的接口号表的o / p。我在编写脚本时遇到了实现问题,即无法实现像Linked List,Two Dimensional array这样的数据结构。 我在TCL中使用多维数组(将值传递到进程内外的数组中)来重写脚本,以扫描每个.txt文件并搜索字符串/正则表达式“Interface#”来计算并显示数字发生的事。如果有人能帮助我完成这部分,将不胜感激。
这是我在当前目录中搜索.txt文件的代码
set files [glob *.txt]
if { [llength $files] > 0 } {
puts "Files:"
foreach f [lsort $files] {
puts " [file size $f] - $f"
}
} else {
puts "(no files)"
}
我认为这些是完成它的所有可能的逻辑步骤 i)搜索并找到.txt文件后,以只读模式打开所有.txt文件 ii)使用过程(proc)创建一个数组或列表接口号为NULL,接口计数为零0 iii)扫描.txt文件并搜索字符串或正则表达式“interface#” iv)当在.txt文件中找到匹配项时,请检查接口编号并增加相应条目的计数。否则,将新元素添加到“接口编号”列表中 v)如果没有文件返回第一个目录
我的o / p如下:
Interface Frequency
123f 3
1232 4
答案 0 :(得分:1)
编辑按名称而不是全局变量使用数组。
我认为你想要的东西就是这样的。您可以在每个文件上拨打scan_for_interface
,并在结束时拨打print_report
。你可以变得更加漂亮并将其包装在Itcl班级或namespace中。 scan_for_interface
的第二个参数是用于存储结果的数组的名称,该名称将传递给print_report
。 regexp链接将说明regexp
的工作原理:
proc scan_for_interface {file arrayname} {
upvar $arrayname array
set fh [open $file r]
while {[gets $fh line] >= 0} {
if {[regexp -- {Interface # ([[:xdigit:]]{4}|[[:xdigit:]]{32})$} $line ignore num]} {
if {[info exists array($num)]} {
incr array($num)
} else {
set array($num) 1
}
}
}
close $fh
}
proc print_report {arrayname} {
upvar $arrayname array
puts "Interface Frequency"
set fmt "%s %d"
foreach {interface number} [array get array] {
puts [format $fmt $interface $number]
}
}
# the following is a proc that takes the question's code
# and incorporates the calls to the accounting functions
proc dosearch {} {
set files [glob *.txt]
if { [llength $files] > 0 } {
puts "Files:"
foreach f [lsort $files] {
puts " [file size $f] - $f"
scan_for_interface $f tally
}
print_report tally
} else {
puts "(no files)"
}
}
答案 1 :(得分:0)
不是全局的忠实粉丝,我会选择Trey使用的东西,但让它返回当前文件的结果的dict(或数组get),并将它们合并到一个dict(或数组)中)保持在来电水平。