Search code examples
tclputs

Error : can't read "line2": no such variable in tcl


I have a script with this snippet:

 while {[gets $fin line] != -1} {
 if {[string first "Modem :" $line] != -1} {
            set line2 [string range $line 17 end]
            puts $fout "One : \t$line2"
    }

    puts $fout "Two : \t$line2"
 }

The One : works and prints the output (when i don't include the Two : part in the script) but when I include Two : , it shows

error : can't read "line2": no such variable
    while executing
"puts $fout "Two : \t$line2""
    ("while" body line 14)

Doesn't it hold the value of line2 after coming out of if ?


Solution

  • From chat, this is a sample of $fin.

    The problem with the code is that while {[gets $fin line] != -1} loops through each line of $fin one at a time, and not a whole bunch together. read is the command that gets all lines in one variable.

    This means that when the first line is read, you don't have $line1 or $line2 in the first iteration of the loop and thus, puts will fail to retrieve a variable by those names.

    My proposed solution is to get each of the required variables first and when everything is gathered for the 'blocks', print them all at once.

    set fin [open imp_info r]
    set fout [open imfp_table w]
    
    puts $fout "LINK\tModem Status"
    puts $fout "----\t------------"
    
    while {[gets $fin line] != -1} {
    
            # If there is "wire-pair (X)" in the line, get that number
            regexp -- {wire-pair \(([0-9]+)\)} $line - wire_pair_no
    
            # Last column, get the value and puts everything
            if {[regexp -- {Modem status: ([^,]+)} $line - status]} {
                   puts $fout "$wire_pair_no\t$status"
            }
    
    }
    

    Output:

    LINK    Modem Status    
    ----    ------------
    0       UP_DATA_MODE
    1       UP_DATA_MODE