如何在TCL中操作文件中的每一行

时间:2012-02-24 22:02:12

标签: tcl

我正在尝试使用tcl脚本将一些数据从iperf写入文件。该文件有超过100行。现在我需要解析前10行,忽略它并考虑下一组10行并打印它,再次我需要忽略下一组10行并打印下10行然后继续直到我到达结尾文件。我怎么能以程序化的盟友呢?

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 个答案:

答案 0 :(得分: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]

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

答案 1 :(得分: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命令。