0

I have this data

# Curve 0 of 2, 7 points
# x y xlow xhigh type
20.781 1 20.781 20.781
20.8102 10 20.8102 20.8102
20.8395 18 20.8395 20.8395
20.8687 13 20.8687 20.8687
20.898 15 20.898 20.898
20.9273 18 20.9273 20.9273
20.9565 13 20.9565 20.9565

# Curve 1 of 2, 7 points
# x y xlow xhigh type
21.635 2 21.635 21.635
21.6625 19 21.6625 21.6625
21.6899 29 21.6899 21.6899
21.7173 63 21.7173 21.7173
21.7447 137 21.7447 21.7447
21.7721 168 21.7721 21.7721
21.7996 109 21.7996 21.7996

All the information is an unique file, i.e block data are separated by three blank lines. I want to collect the information that is just at the beginning of the next line that has characters # x y xlow xhigh type. Also I want to collect the information that is at the end of each block. In other words, I want to print on screen the values that are in bold letter (20.781 20.9565 21.635 21.7996).

I wrote these lines of code but I don't know how to print the info that is just below the characters # x y.

set input [open "dataHist.dat" r]

while { [gets $input line] != -1 } {
   if { [string range 0 4] == "# x y"} {
      
   }
}
  • This is a case where you want to save the _previous_ line: when the previous line contains "# x y", print the _current_ line; when the current line is blank (or you're at end-of-file), print the _previous_ line – glenn jackman Jul 13 '22 at 23:23

1 Answers1

1

Since the first line of each block tells you long it is, you can use that to tell which lines you want to extract the first number from:

#!/usr/bin/env tclsh                                                                                                                                                                                                                             

proc must_gets {ch var_} {
    upvar $var_ var
    if {[gets $ch var] < 0} {
        error "Premature end of file"
    }
}

proc extract_numbers {filename} {
    set ch [open $filename]
    try {
        set nums {}
        while {[gets $ch line] >= 0} {
            if {[regexp {^# Curve \d+ of \d+, (\d+) points} $line -> nPoints]} {
                must_gets $ch line ;# Discard '# x y ...' line.                                                                                                                                                                                  
                must_gets $ch line ;# First point line
                # Extract first element of it                                                                                                                                                                                                    
                lappend nums [lindex [split $line] 0]                                                                                                                                                                                            
                # Read remaining point lines                                                                                                                                                                                                     
                for {set n 2} {$n <= $nPoints} {incr n} {
                    must_gets $ch line
                }
                # And extract first element of last one                                                                                                                                                                                   
                lappend nums [lindex [split $line] 0]
            }
        }
        return $nums
    } finally {
        chan close $ch
    }
}

# 20.781 20.9565 21.635 21.7996                                                                                                                                                                                                                  
puts [extract_numbers dataHist.dat]
Shawn
  • 47,241
  • 3
  • 26
  • 60