String TCL字符串匹配不工作

String TCL字符串匹配不工作,string,file,tcl,match,String,File,Tcl,Match,我试图在一个大的文本文件中搜索一个字符串,并相应地返回一个退出代码。对于上下文,文本文件是ModelSim日志文件,我需要将退出代码1(坏)或0(好)传递给正在调用以下TCL脚本(代码段)的Windows批处理脚本: 当我执行上述脚本时,至少有两件事情出错: 该日志文件将在没有换行符的情况下回显到我的Windows命令shell。如果我注释掉“#读取日志文件”之后的所有内容,则不会出现这种情况 即使该字符串出现在日志文件中,退出代码也为0 我做错了什么 [编辑]: 谢谢大家的回复。不幸的是,我仍

我试图在一个大的文本文件中搜索一个字符串,并相应地返回一个退出代码。对于上下文,文本文件是ModelSim日志文件,我需要将退出代码1(坏)或0(好)传递给正在调用以下TCL脚本(代码段)的Windows批处理脚本:

当我执行上述脚本时,至少有两件事情出错:

  • 该日志文件将在没有换行符的情况下回显到我的Windows命令shell。如果我注释掉“#读取日志文件”之后的所有内容,则不会出现这种情况
  • 即使该字符串出现在日志文件中,退出代码也为0
  • 我做错了什么

    [编辑]: 谢谢大家的回复。不幸的是,我仍然无法让我的TCL脚本工作。这可能与我的日志文件包含以下我正在搜索的文本字符串有关:

    # ** Failure: ERRORS. End of Test: FAIL
    
    我无法更改文本的第一部分“#**Failure:”,因为这是ModelSim用于日志文件的语法。所以“**”可能会搞砸字符串匹配,因为我不知道如何逃逸它

    我真正想做的是搜索子字符串“ERRORS.End of Test:FAIL”,这是我可以更改的文本

    注意,我在foreach循环中使用string命令


    我仍在将整个日志文件的疯狂长回声发送到我的Windows命令窗口,该窗口也会写入日志文件(不带换行符)。很抱歉,我没有正确打开/关闭日志文件,因此我在原始代码段中添加了更多内容。

    第一个问题是由-nonewline引起的。移除它

    set log_data [read $fptr]
    
    如果将其保留在中,日志数据将不包含换行符,因此
    split$log\u data“\n”
    将是长度为1的列表

    可能是exit命令的
    -code
    选项。我找到的文档表明它不是一个受支持的选项(没有用于退出的选项)。您以前可能有一个
    return
    语句,它支持-code属性。试一试

    exit $failed_sim
    

    那么,这些模式的问题是:

    set sim_ok {# ** Failure: NONE. End of Test: PASS};
    set sim_fail {# ** Failure: ERRORS. End of Test: FAIL};
    
    对于由
    字符串匹配支持的glob模式,您必须匹配整个字符串,即使在拆分为行之后,其中也可能存在意外字符。其中可能有其他您不期望的东西(例如,颜色代码),但这些最终还是需要匹配的字符。此外,行的末尾可能有空格,全局模式中的
    **
    *
    相同,并且匹配任意字符的任意数量

    诊断提示 您可以通过以下操作发现此类问题:

    puts [exec od -c << $the_line_contents]
    
    并与以下对象进行模式匹配:

    if {[string match $sim_fail [string trim $each_line]]} {
       ...
    
    处理彩色输出(如果有问题)的最简单方法是在运行生成输出的程序之前,将
    术语
    环境变量更改为不支持颜色的变量,例如
    vt100
    普通



    exit
    命令不接受
    -code
    选项。只需使用直接的
    退出1
    即可执行此程序失败的退出。

    对于匹配精确的子字符串(不是正则表达式或全局模式),这是一个很好的工具:

    set sim_fail {# ** Failure: ERRORS. End of Test: FAIL};
    set each_line "# ** Failure: ERRORS. End of Test: FAIL\r"   ;# trailing whitespace
    
    if {[string match $sim_fail $each_line]} {puts matched} else {puts "not matched"}
    # => not matched
    
    if {[string first $sim_fail $each_line] != -1} {puts matched} else {puts "not matched"}
    # => matched
    

    在对我的TCL脚本进行了一些调试之后,我让它开始工作了。解决办法是:

  • 在“我的文件”前面添加“安静”读取:

    quietly set line_data [split [read -nonewline $fptr] "\n"]
    
  • 这将关闭ModelSim的转录本回显,ModelSim是我使用的TCL解释器

  • 将“break”命令的缩进和错位修复为:

    foreach each_line $line_data {
        if {[string match $sim_fail $each_line]} {
          set failed_sim 1
          break
        }
    }
    

  • 谢谢你的帮助

    如果是换行符,-nonewline选项仅删除最后一个字符。所有其他换行符都保留在文本中。
    quietly set line_data [split [read -nonewline $fptr] "\n"]
    
    foreach each_line $line_data {
        if {[string match $sim_fail $each_line]} {
          set failed_sim 1
          break
        }
    }