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