如何从tcl中的文件中获取两个字符串之间的数据?

时间:2013-03-08 11:27:50

标签: tcl

在TCL脚本中: 我有一个文件,我知道如何搜索字符串,但如何找到字符串时获取行号。如果可能,请回答我

set fd [open test.txt r]
while {![eof $fd]} {
    set buffer [read $fd]
}

set lines [split $buffer "\n"]
if {[regexp "S1 Application Protocol" $lines]} {
    puts "string found"
} else {puts "not found"}
#puts $lines

#set i 0
#while {[regexp -start 0 "S1 Application Protocol" $line``s]==0}  {incr i
#puts $i
#}

#puts  [llength $lines]
#puts [lsearch -exact $buffer  S1]
#puts [lrange $lines 261 320]

在上面的程序中我得到输出为字符串找到。如果我将给出该文件以外的字符串我得到字符串未找到。

2 个答案:

答案 0 :(得分:0)

'a line'的概念只是我们在文件中获取的数据流之上的一种约定。因此,如果您想使用行号,那么您必须自己计算它们。 gets命令文档包含以下示例:

set chan [open "some.file.txt"]
set lineNumber 0
while {[gets $chan line] >= 0} {
    puts "[incr lineNumber]: $line"
}
close $chan

因此,您只需将puts语句替换为您的代码即可找到您要查找的文本模式,当您找到它时,$line的值会为您提供行号。

要复制位于其他两行之间的文本,我会使用类似下面的内容

set chan [open "some.file.txt"]
set out [open "output.file.txt" "w"]
set lineNumber 0
# Read until we find the start pattern
while {[gets $chan line] >= 0} {
    incr lineNumber
    if { [string match "startpattern" $line]} {
        # Now read until we find the stop pattern
        while {[gets $chan line] >= 0} {
            incr lineNumber
            if { [string match "stoppattern" $line] } {
                close $out
                break
            } else {
                puts $out $line
            }
        }
    }
}
close $chan

答案 1 :(得分:0)

最简单的方法是使用fileutil::grep命令:

package require fileutil

# Search for ipsum from test.txt
foreach match [fileutil::grep "ipsum" test.txt] {
    # Each match is file:line:text
    set match      [split $match ":"]
    set lineNumber [lindex $match 1]
    set lineText   [lindex $match 2]

    # do something with lineNumber and lineText
    puts "$lineNumber - $lineText"
}

更新

我意识到如果该行包含冒号,则lineText在第三个冒号处被截断。所以,而不是:

    set lineText   [lindex $match 2]

我们需要:

    set lineText   [join [lrange $match 2 end] ":"]