amateur
amateur

Reputation: 951

How to manipulate each line in a file in TCL

I'm trying to write some data from iperf to a file using tcl script.The file has more than 100 lines. Now i need to parse the first 10 lines, neglect it and consider the next set of 10 lines and print it, again i need to neglect the next set of 10 lines and print the next 10 lines and keep continuing until i reach the end of file. How could i do it programmatic ally?

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"
    }

Upvotes: 0

Views: 7647

Answers (2)

Hai Vu
Hai Vu

Reputation: 40688

If I understood you correctly, you want to print lines 11-20, 31-40, 51-60,... The following will do what you want:

package require Tclx

set counter 0

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

The Tclx package provides a simple way to read lines from a file: the for_file command.

Upvotes: 0

kostix
kostix

Reputation: 55443

Well, as your example shows, you have found out how to split a (slurped) file into lines and process them one-by-one.

Now what's the problem with implementing "skip ten lines, process ten lines, skip another ten lines etc"? It's just about using a variable which counts lines seen so far plus selecting a branch of code based on its value. This approach has nothing special when it comes to Tcl: there are commands available to count, conditionally select branches of code and control looping.

If branching based on the current value of a line counter looks too lame, you could implement a state machine around that counter variable. But for this simple case it looks like over-engeneering.

Another approach would be to pick the necessary series of lines out of the list returned by split using lrange. This approach might use a nice property of lrange which can be told to return a sublist "since this index and until the end of the list", so the solution really boils down to:

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]

For a small file this solution looks pretty compact and clean.

Upvotes: 2

Related Questions