Once you start dealing with many columns, it gets easier to pull the whole file into memory. (This works well even for surprisingly large files.)
# Read the lines in
set f [open $filename]
set lines [split [string trim [read $f]] "\n"]
close $f
# Do an initial clean up of the data; \S+ matches non-whitespace
set headers [regexp -all -inline {\S+} [lindex $lines 0]]
set data [lmap line [lrange $lines 1 end] {regexp -all -inline {\S+} $line}]
# Properly we'd also validate the data to handle non-numeric junk, but this is just an example...
Now we can define a procedure to get the average of a column by name:
proc columnAverage {name} {
global headers data
# Look up which column it is
set idx [lsearch -exact $headers $name]
if {$idx < 0} {
error "no such column \"$name\""
}
# Get the data from just that column
set column [lmap row $data {lindex $row $idx}]
# Calculate the mean of the column: sum / count
return [expr {[tcl::mathop::+ {*}$column] / double([llength $column])}]
}
You'd call that like this:
puts "average of Elec is [columnAverage Elec]"