我正在从一个文件中读取并需要找到确切的行$(eval $(call CreateTest KEYWORD
以及该行之后的所有内容(因为其余部分都是随机的)。这就是我目前正在尝试找到它的方式,但它总是报告为没有找到匹配的东西。
proc listFromFile {$path1} {
set find {$(eval $(call CreateTest, KEYWORD}
upvar path1 path1
set f [open $path1 r]
set data [split [string trim [read $f]] \n]
close $f
# return [lsearch -all -inline $data *KEYWORD*]
return [lsearch -exact -all -inline $data $find*]
}
注释掉的行是最接近我可以使用的行,但是它会在文件中的任何位置使用KEYWORD拉取任何内容。 KEYWORD可以出现在我不想阅读的行中,因此我需要拉出如上所述的确切行
修改 我应该提到文件的格式是这样的;
$(eval $(call CreateTest, KEYWORD ...
$(eval $(call CreateTest, NOT_KEYWORD ...
$(eval $(call CreateTest, KEYWORD ...
$(eval $(call CreateTest, KEYWORD ...
$(eval $(call CreateTest, NOT_KEYWORD ...
$(eval $(call CreateTest, KEYWORD ...
这意味着我只想拉出包含完全字符串和关键字的行。但是我正在寻找的我不想展示之间有界限
答案 0 :(得分:2)
我认为您应该在阅读时将匹配应用于每一行。
proc getMatchingLines {filename match} {
set result {}
set f [open $filename r]
while {[gets $f line] != -1} {
if {[string match ${find}* $line]} {
lappend result $line
}
}
close $f
return $result
}
set find {$(eval $(call CreateTest, KEYWORD}
set matching [getMatchingLines $filename $find]
foreach line $matching {
# do something with the matching line
}
您可以根据应用程序为每个匹配的行构建结果列表或立即执行某些操作。主要区别在于string match
与regexp不同,没有多个元字符。只有*
和?
是特殊的,所以很容易匹配匹配字符串的行后跟任何内容,即:${find}*
。
答案 1 :(得分:1)
改为使用string first
和string range
:
# foo.tcl
set f [open "data.txt" r]
set body [read $f]
puts -nonewline [string range $body [string first "ccc" $body] [string length $body]]
close $f
测试:
$ cat data.txt
aaa
bbb
ccc
ddd
eee
$ tclsh foo.tcl
ccc
ddd
eee
答案 2 :(得分:1)
我认为在您的代码中,您使用*
作为glob模式。
return [lsearch -exact -all -inline $data $find*]
使用-exact
标志时,它会将*
视为文字*
,从而无法获得所需的结果。删除*
将解决问题。
proc listFromFile {$path1} {
set find {$(eval $(call CreateTest, KEYWORD }
upvar path1 path1
set f [open $path1 r]
set data [split [string trim [read $f]] \n]
close $f
return [lsearch -all -inline $data $find]]
}
答案 3 :(得分:0)
这应该有效:
proc listFromFile path {
set f [open $path r]
set data [split [string trim [read $f]] \n]
close $f
return [lsearch -exact -all -inline $data { KEYWORD}]
}
在我对您之前的问题的回答中,我建议lsearch
(没有-exact
)和KEYWORD*
作为模式,因为这似乎就是您所追求的。考虑到您在此处显示的行,搜索空格字符后跟字符串KEYWORD
似乎更有效。
另一件事:您的参数问题(您尝试使用upvar
解决)是您在参数名称上附加了美元符号。如果省略美元符号,就会得到一个可用的参数名称,就像上面的代码一样(即使使用美元符号也可以使用它,但这要困难得多)。