2012-02-24 464 views
0

我正在尝试使用tcl脚本将一些数据从iperf写入文件。该文件有超过100行。现在我需要解析前10行,忽略它,并考虑下一组10行并打印它,再次我需要忽略下一组10行,并打印下10行并继续下去,直到我到达文件。我怎么能这样做它的程序盟友?如何在TCL中处理文件中的每一行

exec c:\\iperf_new\\iperf -c $REF_WLAN_IPAddr -f m -w 2M -i 1 -t $run_time > xx.txt 

set fp [open "xx.txt" r ] 
set file_data [read $fp] 
set data [split $file_data "\n"] 

foreach line $data { 
    if {[regexp {(MBytes) +([0-9\.]*)} $line match pre tput]==1 } { 
     puts "Throughput: $tput Mbps" 
    } 

回答

2

那么,如您的示例所示,您已经找到了如何将一个(slurped)文件分割成多行并逐个处理它们。

现在实施“跳过十条线,处理十条线,跳过另外十条线”等问题出现了什么问题?它只是使用一个变量来计算迄今为止看到的行数,并根据它的值选择一个代码分支。这种方法在Tcl方面没有什么特别的地方:有可用于计数的命令,有条件地选择代码分支和控制循环。

如果基于行计数器的当前值的分支看起来太蹩脚,那么可以在该计数器变量周围实现一个state machine。但对于这种简单的情况,它看起来像过度生成。

另一种方法是使用lrangesplit返回的列表中挑选必要的一系列行。这种方法可能使用的lrange一个不错的属性,它可以告诉返回一个子表“因为这个指数并直至列表的末尾”,因此该解决方案确实可归结为:

set lines [split [read $fd] \n] 
parse_header [lrange $lines 0 9] 
puts [join [lrange $lines 10 19] \n] 
parse_something_else [lrange 20 29] 
puts [join [lrange $lines 30 end] \n] 

对于小文件,这解决方案看起来非常紧凑和干净

+0

+1而不是一个正常的表情。 jwz会很自豪! – 2012-02-25 08:22:01

0

如果我理解正确的话,你要打印线11-20,31-40,51-60,...以下将做你想要什么:

package require Tclx 

set counter 0 

for_file line xxx.txt { 
    if {$counter % 20 >= 10} { puts $line } 
    incr counter 
} 

的Tclx包提供了一个从文件读取行的简单方法:for_file命令。