【问题标题】:Error : can't read "line2": no such variable in tcl错误:无法读取“line2”:tcl 中没有这样的变量
【发布时间】:2014-07-01 13:33:58
【问题描述】:

我有一个带有这个 sn-p 的脚本:

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

One : 工作并打印输出(当我在脚本中不包含 Two : 部分时)但是当我包含 Two : 时,它会显示

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

if出来后不是还持有line2的值吗?

【问题讨论】:

  • 如果$fin 的第一行没有子字符串Modem :,那么你就不会进入ifline2 还不存在...什么你想做什么?
  • 但我敢肯定,有子字符串。我看过文件
  • 它在文件的 first 行吗?如果不是,那么您会收到错误消息。
  • 我正在尝试构建一个表。greping 为两个这样的if 语句中的两个子字符串。然后在ifs 之外我使用puts $fout "$line1\t$line2"
  • 很抱歉,我没有收到您的上述第二条评论。

标签: tcl puts


【解决方案1】:

在聊天中,this$fin 的样本。

代码的问题是while {[gets $fin line] != -1} 一次循环遍历$fin 的每一行,而不是一堆在一起。 read 是在一个变量中获取所有行的命令。

这意味着当读取第一行时,循环的第一次迭代中没有$line1$line2,因此puts 将无法通过这些名称检索变量。

我建议的解决方案是首先获取每个必需的变量,然后在为“块”收集所有内容后,一次打印它们。

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

}

输出:

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

【讨论】:

    【解决方案2】:

    如果你在这个循环中读到的第一行:

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

    你在它的某处没有“Modem :”,处理if时条件不满足并且变量没有被触及。以下puts 失败,因为line2 变量尚未设置为任何值;那里没有变量,$ 语法根本不喜欢这样。

    一种可能的解决方法是在循环开始之前将line2 设置为:

    set line2 "DUMMY VALUE"
    

    或者您应该将正在读取的变量更改为 line 而不是 line2

    puts $fout "Two : \t$line"
    

    或者你应该在读取变量之前测试它是否存在:

    if {[info exists line2]} {
        puts $fout "Two : \t$line2"
    }
    

    一切都会奏效,但他们做的事情不同,我不知道你想要什么……

    【讨论】:

    • 可以用痕迹做“聪明”的事情,使明显的变量语义失效。不要那样做。真的。 (您不太可能在不知情的情况下这样做。)
    猜你喜欢
    • 1970-01-01
    • 2018-04-23
    • 2019-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-15
    • 2021-09-01
    相关资源
    最近更新 更多