我是脚本编写的初学者,并积极学习TCL用于嵌入式系统的开发。
我必须在当前目录中查找只有.txt格式的文件,统计.txt文件中每个不同的"Interface # nnnn“字符串的事例数,其中nnnn是一个4到32位的最大十六进制数和一个接口号表中的o/p,以防出现。我在写脚本时遇到了实现问题,即无法实现像链表、二维数组这样的数据结构。我正在使用TCL中的多维数组(将值传递到过程内和过程外的数组中)重写脚本,以扫描每个接口文件,并搜索字符串/正则表达式‘.txt #’来计数和显示出现的次数。如果有人能帮助我完成这一部分,将不胜感激。
仅搜索.txt扩展名文件并获取文件的大小
下面是我在present目录中搜索.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)一旦搜索并找到接口文件,然后以只读模式打开所有接口文件ii)使用过程(proc)将接口编号设置为NULL并将接口计数设置为零0来创建数组或列表iii)扫描整个.txt文件并搜索字符串或正则表达式“.txt # iv)当在.txt文件中找到匹配时,检查接口编号并递增相应条目的计数。否则,将新元素添加到接口编号列表v)如果没有文件返回到第一个目录
我的o/p如下
Interface Frequency
123f 3
1232 4发布于 2010-04-27 12:48:02
编辑为按名称使用数组,而不是全局变量。
我想你会想要一些类似的东西。您将对每个文件调用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)"
}
}发布于 2010-04-27 22:13:50
我不太喜欢全局变量,所以我会使用类似Trey的方法,但是让它返回当前文件结果的dict (或array get),并将它们合并成在调用者级别维护的dict (或array)。
https://stackoverflow.com/questions/2717553
复制相似问题